A brief summary of distributed locks

Distributed locks for databases such as MySQL

The design of the lock table: the primary key, the resource field to be locked (unique index), the effective start time, the effective end time, flag (whether the lock is valid).
Locking means inserting a record. If the resource to be locked has been locked, it must be locked. It is impossible to insert the record, because there is a unique index to
unlock, which means to delete the data.
Timed task, regularly check whether the lock has expired, and modify the flag after expiration.

Redis does distributed lock

  • 1. Single-point Redis distributed lock

The redis command is: setnx [key] [value] ex 10
10 seconds. Ex must be placed in the same command to ensure atomicity.
The problem: If the business time is relatively long, it may be 10 seconds, the lock has expired, and the business is not over. It will cause other threads to acquire the lock.
Solution: When the lock is acquired, open a thread to renew (watch dog); @Async getKey, if it is equal to my expected value, renew
it. If the business is executed , it will be renewed . getKey, if the lock is added by yourself, del key (release the lock); you must judge whether it is your own

  • 2.Redis master-slave

Redis will have a single point of failure problem, the solution is master-slave, 1 master, 2 slaves and 3 sentinels

  • 3. Red lock

There is a problem with the Redis master-slave cluster:
one thread acquires the lock, returns successfully, and then the master hangs up, and the key has not been synchronized to the slave; another thread can get the lock, and the setnx can be successful, that is, the lock is successful, that is, two Two threads get the same lock, oversold
Redis master-slave cluster. The problem is solved:
red lock, multiple Redis, such as 5 (1, 2, 3, 4, 5), there is no relationship between these five. The service goes to 1, 2, 3, 4, 5 (in order) to lock, and returns if more than half succeeds, and fails if less than half—the lock is not obtained. At least 3 red locks

Several related questions about Red Lock:
What should I do if one of the five is installed? ?
The program thinks that there are still 5 units, and 3 units are still needed to be more than half. As long as there are three or more Redis, the problem is not big.
If the lock grab fails, the lock that you have grabbed will be released. Therefore, if several threads come to grab it together, no one has grabbed it and there is no problem, and the data is still correct. (The purpose of locking is to ensure data consistency), then release and re-grab

Restart problem
One thread got three locks, and the third one was restarted.
Then the second thread got 3, 4, and 5 locks and was successfully locked. This is the
solution to the red lock problem : the third one —Hang up, delay the start, restart after 24H (shorter time is fine, for example, theoretically a few minutes will be fine)

  • ZK+MySQL Optimistic Lock

JVM STW problem: (JVM cluster) Go to Redis to get the lock (cluster), lock and
lock successfully, and then return.
At this time, the STW is executed and the renewal thread is also stopped. At this time, the key expires; at this time, other threads Come to lock, and the lock is successfully
completed. STW is over, and the business continues to execute. (For example, if you want to change 10 to 9, but here it becomes 8, it’s oversold.)
This problem can't be solved by ostrich and Redis.
In fact, ZK can't solve it. , That is, to establish a temporary node. When the temporary node is gone during STW,
many companies use Redis for locks, and the stability is already very high.
If you really want to solve it (Ali does not use it), Optimistic lock: ZK adds a MySQL, double write, in order to ensure data consistency,
first go to ZK to lock, ZK writes A000 (assuming), and then writes to MySQL, at this time STW, another thread comes to ZK to write A001 (why add 1 ZK feature, the node is incremental), then go to MySQL to update the version to A001, and then the JVM STW of the previous thread is good, and then check in MySQL and find that the version is different, then roll back, and the data can be consistent. promise

In the end,
the simplest and most practical one is to do it with Redis. It mainly depends on business volume and demand.
Pursuing concurrency, using redis, pursuing data consistency, using zk

Guess you like

Origin blog.csdn.net/qq_38238041/article/details/115273101