Simple understanding of distributed transactions and common solutions

what is a transaction

A transaction is a unit of work consisting of a set of operations. How to understand this problem?

We understand from real life

So what are the characteristics of transactions?

transaction characteristics

Atomicity: A set of operations within a transaction either succeeds or fails at the same time

Isolation: Different transactions do not affect each other

Consistency: A set of operations within a transaction, and the result data generated by each operation, must be able to guarantee that they are all in the expected state

Persistence: A set of operations within a transaction, and the data generated by each operation must have a persistent effect

What is a distributed transaction

A distributed transaction is a collection of service operations

For example: in a distributed system or a microservice system, to complete any task, it needs to involve multiple services to complete it together. The set of this group of service operations is a distributed transaction

what is local affairs

A local transaction is a collection operated by a set of SQL statements.

Local transactions mainly refer to the operation of SQL statements

ACID

Refers to the four basic elements for the correct execution of database transactions:

  1. Atomicity
  2. Consistency
  3. Isolation
  4. Durability

CAP

The CAP principle, also known as the CAP theorem, refers to Consistency, Availability, and Partition tolerance in a distributed system. The CAP principle means that these three elements can only achieve at most two points at the same time, and it is impossible to take care of all three.

  • Consistency: Whether all data backups in a distributed system have the same value at the same time.
  • Availability: After some nodes in the cluster fail, whether the cluster as a whole can still respond to the client's read and write requests.
  • Partition tolerance: In terms of practical effect, partition is equivalent to the time limit requirement for communication. If the system cannot achieve data consistency within the time limit, it means that a partition has occurred, and a choice between C and A must be made for the current operation.

BASE theory

The BASE theory is the result of a trade-off between consistency and availability in CAP. The core idea of ​​the theory is: we cannot achieve strong consistency, but each application can use an appropriate method according to its own business characteristics to make the system achieve final consistency.

  • Basically Available
  • Soft state
  • Eventually consistent (final consistency)

undo log

Database transactions are atomic. If the transaction execution fails, the data needs to be rolled back.

Transactions are also durable, and changes made to data by transactions are completely stored in the database and cannot be lost due to failures.

Atomicity can be achieved using undo logs.

The principle of undo log

In order to meet the atomicity of the transaction, before operating any data, first back up the data to the undo log, and then modify the data. If an error occurs or the user executes a rollback (RollBack) statement, the system can use the backup in the undo log to restore the data to the state before the transaction started

When the database writes data to the disk in a straight line, the data will be cached in the memory first, and will be written to the disk when the transaction is committed.

The process of using undo log to achieve atomicity and persistence:

Suppose there are two data in A and B, the values ​​are 1 and 2 respectively

  1. business start
  2. Record A=1 to undo log
  3. Modify A=3
  4. Record B=2 to undo log
  5. Modify B=4
  6. Write undo log to disk
  7. write data to disk
  8. transaction commit

How to ensure persistence?

Before the transaction is committed, the modified data will be sent to the disk, that is, as long as the transaction is committed, the data will definitely be persisted

How to ensure atomicity?

  • Every time the database is modified, the data before the modification will be recorded in the undo log, so when a rollback is required, the undo log can be read and the data restored

  • If the system crashes between 7 and 8

    At this time, the transaction has not been committed and needs to be rolled back, but the undo log has been persisted, and the data can be recovered according to the undo log log

    If the system crashes before 7

    At this time, the data is not persisted to the hard disk, but remains in the state before the transaction

shortcoming:

Before each transaction is committed, the data and undo log will be written to the disk, which will cause a lot of disk IO, so the performance will be very low.

redo log

The redo log records the backup of new data. Before the transaction is committed, it is only necessary to persist the redo log, and there is no need to persist the data, which reduces the number of IOs. It uses sequential IO and all read and write speeds will be very fast

How to ensure persistence

Redo Log records the backup of new data. Before the transaction is committed, as long as the Redo Log is persisted, the data does not need to be persisted. When the system crashes, although the data is not persisted, the Redo Log has been persisted. The system can restore all data to the latest state according to the content of Redo Log.

Two strategies for data recovery:

  • When recovering, only committed transactions are redone
  • When recovering, redo all transactions including uncommitted transactions and rolled back transactions, and then roll back uncommitted transactions through undo log.

The Inodb engine uses the second type, so the undolog should be persisted before the redo log

Summarize:

The undo log records the data before the update to ensure the atomicity of the transaction

The redo log records the updated data to ensure the durability of the transaction

The redo log has its own memory buffer, which is first written to the buffer and written to disk when the transaction is committed

After the redo log is persisted, it means that the transaction can be committed

distributed transaction

Distributed transactions are a collection of a series of operations on data in a distributed environment, expressed by whether the following three characteristics are realized

  • Consistency: The client knows that a series of operations will happen at the same time (take effect)
  • Availability: Every operation must end with a predictable response
  • Partition tolerance (Partition tolerance): Even if a single component is unavailable, the operation can still be completed

Because the system must be deployed on multiple machines in a distributed system, the network cannot be guaranteed to be 100% reliable, so the network partition must exist, that is, P must exist;

After the network partition occurs, the problem of availability and consistency arises. We have to make a trade-off between the two, so there are two architectures: CP architecture and AP architecture;

CP architecture

When a network partition occurs, in order to ensure consistency, the request must be rejected, otherwise the consistency cannot be guaranteed

  1. When there is no network partition, the data of system A and system B are consistent, X=1
  2. Modify X of system A to 2, X=2
  3. When a network partition occurs, the data synchronization data between system A and system B fails, and X=1 of system B
  4. When the client requests system B, in order to ensure consistency, system B should reject the service request and return an error code or error message

The above method violates the requirements of availability and only satisfies consistency and partition fault tolerance, that is, CP

The CAP theory is to ignore the network delay, and the network delay from synchronizing data from system A to system B is ignored

The CP architecture ensures that the client must be the latest write operation when obtaining data, or obtain abnormal information, and there will never be data inconsistency

Strongly consistent, weakly available

AP architecture

When a network partition occurs, in order to ensure availability, system B can return the old value to ensure system availability

  1. When there is no network partition, the data of system A and system B are consistent, X=1
  2. Modify X of system A to 2, X=2
  3. When a network partition occurs, the data synchronization data between system A and system B fails, and X=1 of system B
  4. When the client requests system B, in order to ensure availability, system B should return the old value at this time, X=1

The above method violates the requirement of consistency, and only satisfies availability and partition fault tolerance, that is, AP

The CP architecture ensures that the system must be available regardless of whether the client returns the latest value or the old value when obtaining data.

CAP theory focuses on the granularity of the data, rather than strategies for overall system design

High availability, weak consistency (final consistency)

BASE

1. Understand strong consistency and eventual consistency

The CAP theory tells us that a distributed system can only satisfy at most two of the three items of consistency (Consistency), availability (Availability), and partition tolerance (Partition tolerance). Among them, APs are more common in practical applications, and APs abandon consistency to ensure availability and partition tolerance. However, consistency must be achieved in many scenarios in actual production. Different, the consistency in CAP requires that the data of each node must be consistent at any time. It emphasizes strong consistency, but the final consistency allows the data of each node to be inconsistent for a period of time, but the data of each node must be consistent after a period of time. It emphasizes the consistency of the final data.

2. Introduction to Base theory

BASE is an acronym for the three phrases Basicly Available (basically available), Soft state (soft state) and Eventually consistent (final consistency). The BASE theory is an extension of AP in CAP. It obtains availability by sacrificing strong consistency. When a failure occurs, it allows partial unavailability but ensures the availability of core functions. It allows data to be inconsistent for a period of time, but eventually reaches a consistent state. Transactions that satisfy the BASE theory are called "flexible transactions".

Basic availability: When a distributed system fails, it is allowed to lose part of the available functions to ensure that the core functions are available. For example, there is a problem with the transaction payment on the e-commerce website, but the products can still be browsed normally.
Soft state: Since strong consistency is not required, BASE allows the existence of an intermediate state (also called soft state) in the system. This state does not affect the availability of the system, such as the "payment" and "data synchronization" states of the order. After the data is finally consistent, the state changes to the "successful" state.
Final Consistency: Final Consistency means that after a period of time, all node data will reach consistency. For example, the "Payment" status of the order will eventually change to "Payment Successful" or "Payment Failed", so that the order status is consistent with the actual transaction result, but a certain period of delay and waiting is required.

1. Submit in stages

1. Two-phase commit protocol (2PC: Two-Phrase Commit)

The goal of the two-phase commit protocol is to ensure data consistency in a distributed system: the voting phase and the transaction commit phase

(1) Protocol participants

In the two-phase commit protocol, the system generally includes two types of machines (or nodes): one is the coordinator, usually only one in a system; the other is transaction participants (participants, cohorts or workers), generally including multiple, which can be understood as the number of data copies in the data storage system. The protocol assumes that each node will record a write-ahead log and store it persistently, even if the node fails, the log will not be lost. The protocol also assumes that nodes will not fail permanently and that any two nodes can communicate with each other.

(2) Two-stage execution

1. Request phase (commit-request phase, or voting phase, voting phase)
In the request phase, the coordinator will notify the transaction participants to prepare to commit or cancel the transaction, and then enter the voting process.
During the voting process, participants will inform the coordinator of their decision: agree (transaction participant's local job execution is successful) or cancel (local job execution failure).

2. Commit phase
In this phase, the coordinator will make a decision based on the voting results of the first phase: submit or cancel.
If and only if all participants agree to submit the transaction, the coordinator will notify all participants to submit the transaction, otherwise the coordinator will notify all participants to cancel the transaction.
Participants will perform corresponding operations after receiving messages from the coordinator.

(3) Disadvantages of two-phase commit

1. Synchronous blocking problem. During execution, all participating nodes are transaction blocking.
When participants occupy public resources, other third-party nodes have to be blocked when accessing public resources.

2. Single point of failure. Due to the importance of the coordinator, once the coordinator fails.
Participants will be blocked forever. Especially in the second stage, if the coordinator fails, all participants are still in the state of locking transaction resources, and cannot continue to complete transaction operations. (If the coordinator hangs up, a coordinator can be re-elected, but it cannot solve the problem that the participants are blocked due to the downtime of the coordinator)

3. The data is inconsistent. In the second phase of the two-phase commit, after the coordinator sends the commit request to the participants, a local network exception occurs or the coordinator fails during the process of sending the commit request, which results in only some participants receiving the commit request.
After these participants receive the commit request, they will execute the commit operation. However, other machines that have not received a commit request cannot perform transaction commits. As a result, there is a phenomenon of data consistency in the entire distributed system.

(4) Problems that cannot be solved by two-phase commit

When the coordinator makes mistakes and the participants also make mistakes, the two-phase cannot guarantee the integrity of transaction execution.
Consider that the coordinator went down after sending the commit message, and the only participant who received the message also went down at the same time.
Then even if the coordinator generates a new coordinator through the election agreement, the status of this transaction is uncertain, and no one knows whether the transaction has been committed.

2. Three-phase commit protocol

The three-phase commit protocol introduces a timeout mechanism in both the coordinator and the participants, and splits the first phase of the two-phase commit protocol into two steps: query, then lock resources, and finally commit.

Aiming at the problems of two-phase commit, the three-phase commit protocol introduces a "pre-query disk" phase and a timeout strategy to reduce the blocking time of the entire cluster and improve system performance. The three phases of three-phase commit are:

Phase 1: can_commit

The CanCommit stage of 3PC is actually very similar to the preparation stage of 2PC.
The coordinator sends a commit request to the participant, and the participant returns a Yes response if it can submit, otherwise it returns a No response.

The second stage: pre_commit

The Coordinator decides whether to continue the PreCommit operation of the transaction according to the response of Cohort.
Depending on the response, there are two possibilities.
A. If the Coordinator gets a Yes response from all Cohorts, it will perform pre-execution of the transaction:
send a pre-commit request. The Coordinator sends a PreCommit request to Cohort and enters the Prepared phase.
Transaction precommits. After Cohort receives the PreCommit request, it will execute the transaction operation and record the undo and redo information into the transaction log.
Respond to feedback. If Cohort successfully executes the transaction operation, it returns an ACK response and starts waiting for the final command.

B. If any Cohort sends a No response to the Coordinator, or after waiting for a timeout, the Coordinator does not receive a Cohort response, then interrupt the transaction: send an
interrupt request. Coordinator sends abort requests to all Cohorts.
Interrupt business. After Cohort receives the abort request from the Coordinator (or after a timeout, the Cohort request has not been received), the transaction is interrupted.

The third stage: do_commit

The real transaction committing in this phase can also be divided into the following two situations:

execute commit

A. Send a commit request. Coordinator receives the ACK response sent by Cohort, then he will enter the submission state from the pre-submission state. And send a doCommit request to all Cohorts.
B. Transaction commit. After Cohort receives the doCommit request, it performs a formal transaction commit. And release all transaction resources after completing the transaction commit.
C. Respond to feedback. After the transaction is committed, an ACK response is sent to the Coordinator.
D. Complete the transaction. After the Coordinator receives all Cohort's ACK responses, it completes the transaction.

interrupt transaction

Coordinator does not receive the ACK response sent by Cohort (it may be that the receiver did not send an ACK response, or the response timed out), then the interrupt transaction will be executed.

Disadvantages of the three-phase commit protocol

If after entering PreCommit, the Coordinator sends an abort request, assuming that only one Cohort receives and performs the abort operation,
and other Cohorts who are unknown to the system state will choose to continue Commit according to 3PC, and the system state is inconsistency at this time.

The difference between the three-phase commit protocol and the two-phase commit protocol

A timeout mechanism is set for both the coordinator and the participant (Cohort) (in 2PC, only the coordinator has a timeout mechanism, that is, if the message from cohort is not received within a certain period of time, it will fail by default).
Between the preparation stage and the commit stage of 2PC, a pre-commit stage is inserted, so that 3PC has three stages: CanCommit, PreCommit, and DoCommit.
PreCommit is a buffer that ensures that the state of each participating node is consistent before the final commit phase.

2、TCC

TCC is a relatively mature distributed transaction solution, which can be used to solve the data consistency problem of cross-database operations;

TCC is a service-oriented two-stage programming model, and its Try, Confirm, and Cancel methods are all implemented by business code;

**Try:** operation as a stage, responsible for resource checking and reservation

Confirm : The operation is committed as a two-phase operation, performing real business

Cancel : Cancellation of reserved resources

Implementation process:

Divided into two stages:

Phase 1 (Try): check and reserve resources

Phase 2 (Confirm): Executing real business

advantages and disadvantages

**Advantages:** Each stage of TCC execution will submit local transactions and release locks, without waiting for the execution results of other transactions. If other transactions fail to execute, instead of rolling back, a compensation operation (generate a reverse sql) is performed. This avoids long-term locking and blocking waits for resources. The execution efficiency is relatively high, and it belongs to the distributed transaction method with better performance.

shortcoming:

  • Code invasion: It is necessary to write code to implement Try, Confirm, and cancel. Code hacking is not much
  • High development cost: a business needs to be split into three steps, and the business implementation is written separately, and the business writing is more complicated
  • Security: If the execution of cancel fails, the resource cannot be released, and a retry mechanism needs to be introduced, which may lead to repeated execution, and the idempotent issue of retry should also be considered

scenes to be used

  • There are certain consistency requirements for transactions (eventually consistent)
  • High performance requirements
  • Developers have high coding ability and experience in idempotent processing

3. Reliable message service

Reference: https://blog.csdn.net/qq_39409110/article/details/88081689

Split remote distributed transactions into a series of local transactions

The local transaction of each system is used to realize the distributed transaction.

As the name implies, the local message table has a table for storing local messages, which is usually placed in the database, and then when executing the business, the execution of the business and the operation of putting the message into the message table are placed in the same transaction , so as to ensure that the business of putting the message into the local table must be executed successfully.

Then call the next operation. If the next operation call is successful, the message status of the message table can be directly changed to successful.

It’s okay if the call fails, there will be a background task to read the local message table regularly , filter out the messages that have not been successful, and then call the corresponding service, and change the status of the message after the service update is successful.

At this time, it is possible that the operation corresponding to the message is unsuccessful, so retrying is also required. Retrying must ensure that the corresponding service method is idempotent, and generally there will be a maximum number of retries. If the maximum number of retries is exceeded, an alarm can be recorded for manual processing.

It can be seen that the local message table actually achieves final consistency , which tolerates temporary data inconsistency.

Fundamental

It is generally divided into the initiator A of the transaction and the other participants B of the transaction:

  • Transaction initiator A executes a local transaction
  • Transaction initiator A sends transaction information to be executed to transaction participant B through MQ
  • Transaction participant B executes the local method after receiving the message

How to ensure 100% reliable delivery of messages by upstream services?

How can we ensure 100% reliable delivery of messages, which must be delivered from upstream services to downstream services? Don't worry, let's analyze them one by one.

If there is an error in the process of sending the message to be confirmed by the upstream service to the reliable message service, it does not matter. The upstream service can sense the abnormality of the call, so it does not need to execute the following process, which is no problem.

If the upstream service finishes operating the local database and notifies the reliable message service to confirm the message or delete the message, a problem occurs.

For example: the notification is not successful, or the execution is not successful, or the reliable message service fails to deliver the message to MQ. What should I do if there is a problem with this series of steps?

It doesn't really matter, because in these cases, the status of that message in the database of the reliable message service will always be "pending confirmation".

At this point, we develop a thread that runs regularly in the background in the reliable message service, and constantly checks the status of each message.

If it is always in the "pending confirmation" state, it is considered that there is something wrong with the news. At this time, you can call back an interface provided by the upstream service, and ask, brother, have you executed the database operation corresponding to this message successfully?

If the upstream service replies that my execution is successful, then the reliable message service will modify the message status to "sent" and deliver the message to MQ at the same time.

If the upstream service replies that the execution is not successful, then the reliable message service can delete the message in the database.

Through this mechanism, it can be guaranteed that the reliable message service will try to deliver the message to MQ.

How to ensure 100% reliable reception of messages by downstream services?

Then if there is a problem with the downstream service consumption news, it is not consumed? Or the downstream service failed to process the message, what should I do?

In fact, it doesn't matter, develop a background thread in the reliable message service, and constantly check the status of the message.

If the status of the message is always "Sent" and never becomes "Completed", it means that the downstream service has never been processed successfully.

At this time, the reliable message service can try to re-deliver the message to MQ again, so that the downstream service can process it again.

As long as the interface logic of the downstream service achieves idempotence, it is sufficient to ensure that a message is processed multiple times without inserting duplicate data.

How to implement a reliable message eventual consistency scheme based on RabbitMQ?

4. Seata mode

Therefore, for the message eventual consistency scheme, message consumers must support idempotent consumption of messages, and cannot cause repeated consumption of the same message.






Seata solution
to solve the distributed transaction problem, there are two original design intentions

No intrusion to business: that is, to reduce the intrusion of distributed transaction problems brought about by micro-services in technical architecture to business
High performance: to reduce performance consumption caused by distributed transaction solutions
Seata has two distributed transaction implementation schemes, AT and TCC

The AT mode mainly focuses on the data consistency of multi-DB access, and of course also includes the multi-DB data access consistency problem under multi-service. The
TCC mode mainly focuses on business splitting, and solves the consistency problem of calling between microservices when horizontally expanding resources according to business

Original link: https://blog.csdn.net/hosaos/article/details/89136666

5. AT mode (Automatic Transaction)

It is a non-intrusive distributed transaction solution.

It can be regarded as an optimization of the TCC or two-phase commit model, which solves the problems of code intrusion and complicated coding in the TCC mode

In AT mode, you only need to pay attention to your own "business SQL", and the user's "business SQL" is used as a stage, and the Seata framework will automatically generate the second stage commit and rollback of the transaction

for example:

When a user places an order, the following three-step process is performed:

  1. order system save order
  2. The order system calls the inventory service to reduce the commodity inventory
  3. The order system calls the account service to deduct the user's amount

These three steps are to be managed as a whole transaction and either succeed as a whole or fail as a whole.

Role:

  • Transaction Coordinator (TC): The transaction coordinator maintains the running status of the global transaction and is responsible for coordinating and driving the commit or rollback of the global transaction
  • Transaction Manager ™: controls the boundaries of global transactions, is responsible for opening a global transaction, and finally initiates a global commit or global rollback resolution
  • Resource Manager (RM): Controls branch transactions, is responsible for branch registration, status reporting, and receives instructions from the transaction coordinator to drive the commit and rollback of branch (local) transactions

Basic principles of AT

Seata AT transactions manage global transactions in two stages:
the first stage: execute each branch transaction and return the execution result

In the first stage, the SQL statement you write will be automatically intercepted by the Seata framework. According to your sql, a select will be generated and stored in a mirror named before image, and then your sql will be released, and then the sql will be checked again and stored in the mirror after image.

The second stage: control the final commit or rollback of global transactions

If the resolution is a global commit, the branch transaction has been committed at this time, no synchronous coordination processing is required (only the rollback log needs to be cleaned up asynchronously), and Phase 2 can be completed very quickly

If the decision is a global rollback, RM receives the rollback request from the coordinator, finds the corresponding rollback log record through the XID and Branch ID, generates and executes the reverse update SQL through the rollback record , to complete the rollback of the branch

Guess you like

Origin blog.csdn.net/python_mopagunda/article/details/116724816