This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

preface

In our work, we have more or less used locks, today we are going to discuss the distributed scenario, we can solve the problem of locks, this is also a problem I often meet in the interview, it is very important to deal with it.

Why locks are needed

First of all, why do we need locks? This is because there may be two or more threads executing the same piece of code at the same time. The classic scenario is split-counting inventory, which, if left unchecked, can have unintended consequences, such as oversold problems.

So even if there is no systematic learning of concurrent programming partners, will directly take out the universal method -synchronized, but this way (JVM lock) can only solve the thread safety of a single server, if it is a distributed scenario, this way is certainly unable to meet, this time needs to use distributed lock.

How to implement distributed locking

There are many ways to realize distributed lock, such as database, Redis and ZooKeeper, but no matter which way, its core idea is common, that is, only one thread can acquire the lock at the same time.

For example, now there is an order system, and an instance is deployed on three servers. At the same time, each server wants to operate the state of the same order, but only one server can operate successfully at this time. At this time, the help of distributed lock is needed.

Redis distributed lock

Redis is the most common way to do distributed locks. The reason why Redis can achieve distributed locks is that it is single-threaded, using a single thread to handle all network requests, so there is no need to worry about concurrency security.

As shown in the figure above, system A deploys one instance on each of the three servers. If they all want to modify A certain order information at the same time, what way does Redis implement distributed locking?

Redis has a SET key NX PX 1000 command:

  • NX: If the key does not exist, the setting succeeds.
  • PX 1000: Expiration time is 1000 milliseconds. When the expiration time is exceeded, it will be automatically released.

With this command, when the first thread sets the key, the Redis service returns OK, indicating that the lock has been acquired successfully. Within the timeout period, if another server thread attempts to acquire the lock through this command, the Redis service directly returns nil, indicating that the current lock is occupied by another thread and the acquisition failed.

Problems and solutions

Although the above method can meet the needs of distributed locks, there are several problems that need our attention:

The first is that when you set a value, you must use a random value.

This is because the thread after I get the lock, after in dealing with their business, will be to release the lock (key) in active delete redis, but likely the threads blocked a long time to processing is completed, it may have been released automatically, and is being used by other threads access to, the thread a direct delete key, will inevitably lead to problems.

Therefore, you are advised to set value to a random value. In this way, lua scripts are used to delete keys. Before deleting keys, check whether the value of the key to be deleted is the same as that of the current thread.

The second point is redis single point of failure.

Because if it’s a normal Redis singleton, it’s a single point of failure. If the master node fails and the key is not synchronized to the slave node, the slave node will switch to the master node and someone else will get the lock.

RedLock principle introduction

This scheme is a distributed lock algorithm officially supported by Redis, which is also an optimization of the above method. Here I will briefly introduce the principle.

As shown in the figure above, assume that there are now five Redis nodes, which are independent of each other and do not synchronize with each other. If a thread wants to successfully acquire the lock, it needs to complete the following steps:

  1. Gets the current timestamp in milliseconds;
  2. Take turns trying to create locks on each master node using the same key and random value;
  3. The lock is successful if and only if the lock is obtained from most of the Redis nodes (N/2+1, here 3 nodes) and the time taken to acquire the lock is less than the lock expiration time. ;
  4. The client calculates the lock establishment time. If the lock establishment time is shorter than the timeout period, the lock establishment is successful.
  5. If the lock is not acquired for some reason, such as not being acquired for at least N/2+1 Redis instances or the lock is acquired for longer than the valid time, the client should unlock on all Redis instances.

Problems with RedLock

  1. If thread 1 from three examples to get the lock, but an instance of the three examples of system time to walk a little faster, it holds the lock will be expired was released ahead of time, after his release, and three examples are free, at this time is also can get the lock, thread 2 May appear two threads at the same time the lock is held.
  2. If thread 1 has acquired the lock from three instances, but if one of them restarts and three instances are idle, thread 2 can also acquire the lock, and two threads are holding the lock again.

conclusion

Today, I shared with you the realization of redis in distributed lock, introduced its realization principle and need to pay attention to points, but to tell the truth, REDis used to do distributed lock personally think is not very perfect, generally I do not use it. As for why, in addition to redis own shortcomings, but also with other implementation of the comparison of trade-offs, tomorrow flower brother will continue to take you to understand how to use ZooKeeper to complete the implementation of distributed lock.

So, we are usually how to implement it, might as well share in the comments, to learn more perfect distributed lock implementation.

Feel free to discuss in the comments section. The nuggets will be sending out 100 nuggets in the comments section after the diggnation campaign.