Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

Q: Are you familiar with the use of Redis? How is distributed lock implemented in Redis?

Main points

For Redis to implement distributed locks, the following conditions should be met

Mutual exclusion

  • At any time, only one client can hold the lock.

No deadlock

  • The client crashes while holding the lock without actively unlocking it, and it can also ensure that other clients can lock the lock in the future.

Fault tolerance

  • As long as most Redis nodes are running normally, the client can be locked and unlocked.

achieve

The lock can be achieved directly through the set key value px milliseconds nx command, and unlocked through the Lua script.

//获取锁(unique_value可以是UUID等)
SET resource_name unique_value NX PX  30000

//释放锁(lua脚本中,一定要比较value,防止误解锁)
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

Code explanation

  • The set command uses set key value px milliseconds nx, instead of setnx + expire, the command needs to be executed twice, which guarantees atomicity.
  • To be unique, value can be generated using UUID.randomUUID (). toString () method, which is used to identify which request this lock belongs to, and it can be based on unlocking
  • When releasing the lock, verify the value to prevent unlocking by mistake;
  • Use the Lua script to avoid the concurrency problem of the Check And Set model, because multiple Redis operations are involved when the lock is released (using the eval command to execute the atomicity of the Lua script);

Lock code analysis

First of all, the NX parameter is added to set () to ensure that if the existing key exists, the function will not be called successfully, that is, only one client can hold the lock to satisfy the mutual exclusion. Secondly, because we set an expiration time for the lock, even if the lock holder subsequently crashes without unlocking, the lock will be automatically unlocked when the expiration time expires (that is, the key is deleted), and no deadlock will occur. Finally, because we assign value to requestId, it is used to identify which request this lock belongs to, so when the client is unlocked, it can be verified whether it is the same client.

Unlock code analysis

Pass the Lua code to the jedis.eval () method, and set the parameter KEYS [1] to lockKey and ARGV [1] to requestId. During execution, the value corresponding to the lock is first obtained to check whether it is equal to the requestId, and if they are equal, it is unlocked (key is deleted).

Existing risks

If the node corresponding to the key of the storage lock hangs, there may be a risk of losing the lock, resulting in the situation that multiple clients hold the lock, so that the exclusive use of resources cannot be achieved.

  1. Client A acquires the lock from master
  2. Before the master synchronizes the lock to the slave, the master goes down (Redis master-slave synchronization is usually asynchronous). Master-slave switch, slave node is promoted to master node
  3. Client B has acquired another lock for the same resource that client A has already acquired. As a result, more than one thread has acquired the lock at the same time.

Redlock algorithm appears

This scenario assumes a redis cluster with 5 redis master instances. Then perform the following steps to obtain a lock:

  1. Get the current timestamp in milliseconds;
  2. Similar to the above, in turn try to create a lock on each master node, the expiration time is shorter, generally tens of milliseconds;
  3. Try to establish a lock on most nodes, for example, 5 nodes require 3 nodes n / 2 + 1;
  4. The client calculates the time to establish the lock, if the time to establish the lock is less than the timeout time, even if the establishment is successful;
  5. If the lock establishment fails, then the previously created locks are deleted in sequence;
  6. As long as someone else establishes a distributed lock, you have to keep polling to try to acquire the lock.

 

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

Redis officially gives the above two methods for implementing distributed locks based on Redis. Detailed instructions can be viewed:

https://redis.io/topics/distlock 。

Redisson

Redisson is a Java In-Memory Data Grid implemented on the basis of Redis. It not only provides a series of distributed Java common objects, but also implements reentrant lock (Reentrant Lock), fair lock (Fair Lock, interlock (MultiLock), red lock (RedLock), read-write lock (ReadWriteLock) And so on, it also provides many distributed services.

Redisson provides the easiest and most convenient way to use Redis. The purpose of Redisson is to promote the separation of concerns of users on Redis (Separation of Concern), so that users can focus more on processing business logic.

Redisson distributed reentrant lock usage

Redisson supports single-point mode, master-slave mode, sentinel mode, and cluster mode. Here, the single-point mode is used as an example:

// 1.构造redisson实现分布式锁必要的Config
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:5379").setPassword("123456").setDatabase(0);
// 2.构造RedissonClient
RedissonClient redissonClient = Redisson.create(config);
// 3.获取锁对象实例(无法保证是按线程的顺序获取到)
RLock rLock = redissonClient.getLock(lockKey);
try {
    /**
     * 4.尝试获取锁
     * waitTimeout 尝试获取锁的最大等待时间,超过这个值,则认为获取锁失败
     * leaseTime   锁的持有时间,超过这个时间锁会自动失效(值应设置为大于业务处理的时间,确保在锁有效期内业务能处理完)
     */
    boolean res = rLock.tryLock((long)waitTimeout, (long)leaseTime, TimeUnit.SECONDS);
    if (res) {
        //成功获得锁,在这里处理业务
    }
} catch (Exception e) {
    throw new RuntimeException("aquire lock fail");
}finally{
    //无论如何, 最后都要解锁
    rLock.unlock();
}

Lock flow chart

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

Unlock flow chart

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

We can see that RedissonLock is reentrant, and considering the failure to retry, you can set the maximum wait time for the lock. Some optimizations have been made in the implementation to reduce invalid lock applications and improve resource utilization.

It is important to note that RedissonLock also does not solve the problem of the risk of losing the lock when the node hangs. The reality is that there are some scenarios that cannot be tolerated, so Redisson provides RedissonRedLock that implements the redlock algorithm. RedissonRedLock really solves the problem of single-point failure at the cost of requiring an additional Redis environment for RedissonRedLock.

Therefore, if the business scenario can tolerate such small probability errors, RedissonLock is recommended, and if it cannot be tolerated, RedissonRedLock is recommended.

At last

Programmer friends who need selected interview questions and answers, Java architect ’s learning materials and learning videos can like and follow. Then reply to the “information” by private message and you can get it for free.

(Welfare at the end of the article: the actual white paper of the horse soldiers' online car-hailing project)

Advanced development framework learning materials

Source code combat books

 

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

 

A full set of videos for intermediate and advanced architecture videos

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

 

Dachang Interview Collection

 

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

 

 

 

Online car-hailing project

 

Huawei Social Recruitment Interview Strategy: How is distributed lock implemented in Redis?

Published 238 original articles · Like 68 · Visits 30,000+

Guess you like

Origin blog.csdn.net/qq_45401061/article/details/105374641