Tuesday, April 6, 2021

Using sagas to maintain data consistency in a microservice architecture by Chris Richardson

 April 6, 2021

Here is the link. 

The microservice architecture structures an application as a set of loosely coupled, collaborating services. Maintaining data consistency is challenging since each service has its own database to ensure loose coupling. To make matters worse, for a variety of reasons distributed transactions using JTA are not an option for modern applications. In this talk we describe an alternative transaction model known as a saga. You will learn about the benefits and drawbacks of using sagas. We describe how sagas are eventually consistent rather than ACID and what this means for developers. You will learn how to design and implement sagas in a Java application. Chris Richardson is a developer and architect. He is the author of POJOs in Action, which describes how to build enterprise Java applications with frameworks such as Spring and Hibernate. Chris was also the founder of the original CloudFoundry.com, an early Java PaaS for Amazon EC2. Today, he is a recognized thought leader in microservices. Chris is the creator of http://microservices.io​, a website describing how to develop and deploy microservices. He provides microservices consulting and training and is working on his third startup http://eventuate.io​, an application platform for developing microservices.

Agenda [3:58] ACID is not an option [5:04] (Scenario: Customer has a credit limit) [5:13] Transactions in a monolithic architecture [5:58] Concurrent transaction for the same customer will be serialized [7:15] Microservices [9:00] Microservice architecture [10:30] Loose coupling = encapsulated data [11:13] 2PC is not an option [13:41] Overview of sagas [15:01] Use Sagas instead of 2PC [15:14] Create Order Saga [16:22] Rollback using compensating transactions [18:20] Saga: Every Ti has a Ci [19:08] Create Order Saga - rollback [20:30] Sagas complicate API design [22:03] Request initiate the saga. When to send back the response? Option #1: Send response when saga completes - Response specifies the outcome - Reduced availability Option #2: Send response immediately after creating the saga (recommended) - Improved availability - Response does not specify the outcome. Client must poll or be notified Revised Create Order API [24:41] createOrder() returns id of newly created order NOT fully validated getOrder(id) called periodically by client to get outcome of validation Minimal impact on UI [25:22] UI hides asynchronous API from the user Saga will usually appear instantaneous (<= 100ms) If it takes longer => UI displays "processing" popup Server can push notification to UI Sagas complicate the business logic [26:33] Coordinating sagas [28:33] How to sequence the saga transactions? [28:41] After the completion of transaction Ti "something" must decide what step to execute next Success: which T(i+1) - branching Failure: C(i-1) Option#1: Choreography-based coordination (distributed) [29:45] Option#2: Orchestration-based coordination (centralized) [30:16] Saga orchestrators are state machines [30:48] Implicit vs. explicit orchestrator [31:47] Event-based, implicit orchestrator [32:38] Explicit orchestration [34:05] Create Order Saga (code sample) [35:12] Initializing the saga [37:20] Handling a reply [37:58] Customer Service - command handling [38:28] Transactional messaging [39:18] About Saga orchestrator ⇔ participant communication [39:22] Messaging channels [40:52] Create Order Saga messaging [41:31] Messaging must be transactional [41:59] 2PC still isn't an option [43:06] Use database table as a message queue [43:22] Publishing message using polling [44:33] Transaction log tailing [46:17] About transaction log tailing [46:57] MySQL master-slave replication protocol DynamoDB table streams Summary [48:13]



ACAD stock: Analyst estimation | another 20% drop | ACAD 150 shares, capital $3872.00

April 6, 2021

 $ACAD

Downgraded by Mizuho Securities Buy » Neutral USD 37 » USD 25
Downgraded by Jefferies Buy » Hold USD 40 » USD 21
Downgrades Goldman Sachs Neutral USD 73 » USD 25
Target Raised by Cantor Fitzgerald Overweight USD 33 » USD 45
Target Lowered by SVB Leerink Outperform USD 63 » USD 31
Downgrades Canaccord Genuity Hold USD 40 » USD 26
Target Lowered by Morgan Stanley Overweight USD 50 » USD 28
Maintains Needham & Company LLC Buy USD 44 » USD 30






Clemens Vasters: Sagas

 April 6, 2021

Here is the article. 

Sagas come out of the realization that particularly long-lived transactions (originally even just inside databases), but also far distributed transactions across location and/or trust boundaries can't easily be handled using the classic ACID model with 2-Phase commit and holding locks for the duration of the work. Instead, a Saga splits work into individual transactions whose effects can be, somehow, reversed after work has been performed and committed.


System design: Micrososervice -> Saga pattern -> eventual consistency | Compensating Transaction pattern

 

April 6, 2021

What I like to do is to highlight things important for me as a first time reader. I will come back to read more times on this article. I am working on Microservice book reading written by Chris Richardson, and then I googled Saga, and then found well-written article with four related articles. The following article is my favorite one. 

My notes:
  1. The eventual consistency model
  2.  Strong transactional consistency   | cloud solution | distributed system | 
  3.  Eventual consistency

Compensating Transaction pattern

Undo the work performed by a series of steps, which together define an eventually consistent operation, if one or more of the steps fail. Operations that follow the eventual consistency model are commonly found in cloud-hosted applications that implement complex business processes and workflows.

Context and problem

Applications running in the cloud frequently modify data. This data might be spread across various data sources held in different geographic locations. To avoid contention and improve performance in a distributed environment, an application shouldn't try to provide strong transactional consistency. Rather, the application should implement eventual consistency. In this model, a typical business operation consists of a series of separate steps. While these steps are being performed, the overall view of the system state might be inconsistent, but when the operation has completed and all of the steps have been executed the system should become consistent again.

The Data Consistency Primer provides information about why distributed transactions don't scale well, and the principles of the eventual consistency model.

A challenge in the eventual consistency model is how to handle a step that has failed. In this case it might be necessary to undo all of the work completed by the previous steps in the operation. However, the data can't simply be rolled back because other concurrent instances of the application might have changed it. Even in cases where the data hasn't been changed by a concurrent instance, undoing a step might not simply be a matter of restoring the original state. It might be necessary to apply various business-specific rules (see the travel website described in the Example section).

If an operation that implements eventual consistency spans several heterogeneous data stores, undoing the steps in the operation will require visiting each data store in turn. The work performed in every data store must be undone reliably to prevent the system from remaining inconsistent.

Not all data affected by an operation that implements eventual consistency might be held in a database. In a service oriented architecture (SOA) environment an operation could invoke an action in a service, and cause a change in the state held by that service. To undo the operation, this state change must also be undone. This can involve invoking the service again and performing another action that reverses the effects of the first.

Solution

The solution is to implement a compensating transaction. The steps in a compensating transaction must undo the effects of the steps in the original operation. A compensating transaction might not be able to simply replace the current state with the state the system was in at the start of the operation because this approach could overwrite changes made by other concurrent instances of an application. Instead, it must be an intelligent process that takes into account any work done by concurrent instances. This process will usually be application specific, driven by the nature of the work performed by the original operation.

A common approach is to use a workflow to implement an eventually consistent operation that requires compensation. As the original operation proceeds, the system records information about each step and how the work performed by that step can be undone. If the operation fails at any point, the workflow rewinds back through the steps it's completed and performs the work that reverses each step. Note that a compensating transaction might not have to undo the work in the exact reverse order of the original operation, and it might be possible to perform some of the undo steps in parallel.

This approach is similar to the Sagas strategy discussed in Clemens Vasters’ blog.

A compensating transaction is also an eventually consistent operation and it could also fail. The system should be able to resume the compensating transaction at the point of failure and continue. It might be necessary to repeat a step that's failed, so the steps in a compensating transaction should be defined as idempotent commands. For more information, see Idempotency Patterns on Jonathan Oliver’s blog.

In some cases it might not be possible to recover from a step that has failed except through manual intervention. In these situations the system should raise an alert and provide as much information as possible about the reason for the failure.

Issues and considerations

Consider the following points when deciding how to implement this pattern:

It might not be easy to determine when a step in an operation that implements eventual consistency has failed. A step might not fail immediately, but instead could block. It might be necessary to implement some form of time-out mechanism.

-Compensation logic isn't easily generalized. A compensating transaction is application specific. It relies on the application having sufficient information to be able to undo the effects of each step in a failed operation.

You should define the steps in a compensating transaction as idempotent commands. This enables the steps to be repeated if the compensating transaction itself fails.

The infrastructure that handles the steps in the original operation, and the compensating transaction, must be resilient. It must not lose the information required to compensate for a failing step, and it must be able to reliably monitor the progress of the compensation logic.

A compensating transaction doesn't necessarily return the data in the system to the state it was in at the start of the original operation. Instead, it compensates for the work performed by the steps that completed successfully before the operation failed.

The order of the steps in the compensating transaction doesn't necessarily have to be the exact opposite of the steps in the original operation. For example, one data store might be more sensitive to inconsistencies than another, and so the steps in the compensating transaction that undo the changes to this store should occur first.

Placing a short-term timeout-based lock on each resource that's required to complete an operation, and obtaining these resources in advance, can help increase the likelihood that the overall activity will succeed. The work should be performed only after all the resources have been acquired. All actions must be finalized before the locks expire.

Consider using retry logic that is more forgiving than usual to minimize failures that trigger a compensating transaction. If a step in an operation that implements eventual consistency fails, try handling the failure as a transient exception and repeat the step. Only stop the operation and initiate a compensating transaction if a step fails repeatedly or irrecoverably.

Many of the challenges of implementing a compensating transaction are the same as those with implementing eventual consistency. See the section Considerations for Implementing Eventual Consistency in the Data Consistency Primer for more information.

When to use this pattern

Use this pattern only for operations that must be undone if they fail. If possible, design solutions to avoid the complexity of requiring compensating transactions.

Example

A travel website lets customers book itineraries. A single itinerary might comprise a series of flights and hotels. A customer traveling from Seattle to London and then on to Paris could perform the following steps when creating an itinerary:

  1. Book a seat on flight F1 from Seattle to London.
  2. Book a seat on flight F2 from London to Paris.
  3. Book a seat on flight F3 from Paris to Seattle.
  4. Reserve a room at hotel H1 in London.
  5. Reserve a room at hotel H2 in Paris.

These steps constitute an eventually consistent operation, although each step is a separate action. Therefore, as well as performing these steps, the system must also record the counter operations necessary to undo each step in case the customer decides to cancel the itinerary. The steps necessary to perform the counter operations can then run as a compensating transaction.

Notice that the steps in the compensating transaction might not be the exact opposite of the original steps, and the logic in each step in the compensating transaction must take into account any business-specific rules. For example, unbooking a seat on a flight might not entitle the customer to a complete refund of any money paid. The figure illustrates generating a compensating transaction to undo a long-running transaction to book a travel itinerary.

Generating a compensating transaction to undo a long-running transaction to book a travel itinerary

 Note

It might be possible for the steps in the compensating transaction to be performed in parallel, depending on how you've designed the compensating logic for each step.

In many business solutions, failure of a single step doesn't always necessitate rolling the system back by using a compensating transaction. For example, if—after having booked flights F1, F2, and F3 in the travel website scenario—the customer is unable to reserve a room at hotel H1, it's preferable to offer the customer a room at a different hotel in the same city rather than canceling the flights. The customer can still decide to cancel (in which case the compensating transaction runs and undoes the bookings made on flights F1, F2, and F3), but this decision should be made by the customer rather than by the system.

The following patterns and guidance might also be relevant when implementing this pattern:

  • Data Consistency Primer. The Compensating Transaction pattern is often used to undo operations that implement the eventual consistency model. This primer provides information on the benefits and tradeoffs of eventual consistency.

  • Scheduler-Agent-Supervisor pattern. Describes how to implement resilient systems that perform business operations that use distributed services and resources. Sometimes, it might be necessary to undo the work performed by an operation by using a compensating transaction.

  • Retry pattern. Compensating transactions can be expensive to perform, and it might be possible to minimize their use by implementing an effective policy of retrying failing operations by following the Retry pattern.

MCFE stock: My IPO stock first purchase | Lessons learned | Comparison to GLSI stock

 April 6, 2021

Introduction

I like to document my IPO stock lesson learned through my own experience from Oct. 2020 to April 6, 2021. I like to compare GLSI stock IPO stock as well. 

My purchase 

I should not work on market fluctuate and worry too much about market value, think about value of the company. 




Comparison to GLSI stock