当前位置:网站首页>Implementation of reliable distributed locks redlock and redisson
Implementation of reliable distributed locks redlock and redisson
2022-06-27 19:17:00 【User 3147702】
1. introduction
In the previous article , We introduced in detail based on redis Implementation of distributed transaction lock based on :
much , There are so many holes in the distributed lock
We see , How to improve the distributed lock scheme step by step and finally realize its high availability .
But then “ High availability ” Come on , It still seems to be lacking , That is, if what he relies on redis It's a single point , If something goes wrong , Then the distributed locks of the whole business will not be used , Even if we are going to order redis Upgrade to redis Master slave mode or cluster , For fixed key Come on ,master Nodes still exist independently , Due to the time interval of master-slave synchronization , If in the meantime master Node failure ,slaver The node is elected master node , that ,master The distributed lock information stored on the node may be lost , Thus creating competitive conditions .
that , How to avoid this situation ?
redis Officials have given based on multiple redis High availability distributed lock solution for cluster deployment — RedLock, In this article, we will introduce in detail .
2. RedLock The process of adding and unlocking
Based on the above theory , We know ,RedLock It's in multiple Redis The implementation of a distributed lock deployed on a cluster , He effectively avoided the single point problem .
Suppose we have N individual Redis Service or cluster ,RedLock The locking process of is as follows :
- client Get the current millisecond time stamp , And set the timeout TTL
- In order to N individual Redis The service makes a request , Use a that is globally unique value To apply for the lock key
- If from N/2+1 individual redis The lock is obtained successfully in the service , that , The acquisition of the distributed lock is considered successful , Otherwise, it will be regarded as failure to acquire the lock .
- If the lock acquisition fails , Or execute to TTL, To all Redis Services all send unlock requests .
3. Java Realization — redisson
java In language ,redisson The package implements the redlock Encapsulation , Mainly through redis client And lua Script implementation , Why lua Script , It is to realize the transaction of adding and unlocking verification and execution .
You were right on the previous homepage redis combination lua There is an article about implementing strict transactions , You can refer to :
Redis Affairs and Redis Lua Script writing
3.1 only ID Generation
Distributed transaction locks , In order to let the storage node as the central node know the lock holder , So as to prevent the lock from being unlocked by non holder , Each person who initiated the request client All nodes must have globally unique id.
Usually we use UUID As the only id,redisson That's how it works , On this basis ,redisson Also joined the threadid Avoid multiple threads repeatedly getting UUID Loss of performance :
protected final UUID id = UUID.randomUUID();
String getLockName(long threadId) {
return id + ":" + threadId;
}3.2 Lock logic
redisson The core code of locking is very easy to understand , By passing in TTL And the only id, Implement a lock request for a period of time .
The following is the implementation logic of reentrant lock :
<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
internalLockLeaseTime = unit.toMillis(leaseTime);
// When getting the lock 5 individual redis The command sent by the instance
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
// Verify the of distributed locks KEY Does it already exist , If it doesn't exist , Then perform hset command (hset REDLOCK_KEY uuid+threadId 1), And pass pexpire Set the expiration time ( It's also the lease time of the lock )
"if (redis.call('exists', KEYS[1]) == 0) then " +
"redis.call('hset', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
// If distributed locks KEY Already exists , Then the verification is unique id, If only id matching , Represents the lock held by the current thread , Then the number of reentries plus 1, And set the failure time
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
// Get distributed lock KEY In milliseconds
"return redis.call('pttl', KEYS[1]);",
// KEYS[1] Corresponding to distributed locks key;ARGV[1] Corresponding TTL;ARGV[2] It's unique id
Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
}3.3 Release lock logic
protected RFuture<Boolean> unlockInnerAsync(long threadId) {
// towards 5 individual redis All instances execute the following commands
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
// If distributed locks KEY non-existent , So channel Post a message
"if (redis.call('exists', KEYS[1]) == 0) then " +
"redis.call('publish', KEYS[2], ARGV[1]); " +
"return 1; " +
"end;" +
// If the distributed lock exists , But the only id Mismatch , Indicates that the lock has been occupied
"if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +
"return nil;" +
"end; " +
// If the current thread holds the distributed lock , Then reduce the number of reentry times 1
"local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +
// Less reentry times 1 If the latter value is greater than 0, Indicates that the distributed lock has been re entered , Then only set the failure time , Don't delete
"if (counter > 0) then " +
"redis.call('pexpire', KEYS[1], ARGV[2]); " +
"return 0; " +
"else " +
// Less reentry times 1 If the latter value is 0, Then delete the lock , And release the unlock message
"redis.call('del', KEYS[1]); " +
"redis.call('publish', KEYS[2], ARGV[1]); " +
"return 1; "+
"end; " +
"return nil;",
// KEYS[1] Indicates the of the lock key,KEYS[2] Express channel name,ARGV[1] Indicates an unlock message ,ARGV[2] Express TTL,ARGV[3] It means only id
Arrays.<Object>asList(getName(), getChannelName()), LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId));
}4. redisson RedLock Use
redisson The implementation of distributed locks is very simple to use :
Config config = new Config();
config.useSentinelServers().addSentinelAddress("127.0.0.1:6369","127.0.0.1:6379", "127.0.0.1:6389")
.setMasterName("masterName")
.setPassword("password").setDatabase(0);
RedissonClient redissonClient = Redisson.create(config);
RLock redLock = redissonClient.getLock("REDLOCK_KEY");
boolean isLock;
try {
isLock = redLock.tryLock(500, 10000, TimeUnit.MILLISECONDS);
if (isLock) {
//TODO if get lock success, do something;
}
} catch (Exception e) {
} finally {
redLock.unlock();
}You can see , because redisson In the implementation of the package , adopt lua The script verifies the... When unlocking client identity , So we don't have to finally To determine whether locking is successful , There is no need for additional identity verification , It can be said that it has reached the level of out of the box .
5. redisson Advanced features of
5.1 Handling of abnormal conditions
One of the most common problems with distributed transaction locks is if the lock has been acquired client stay TTL Failed to complete the processing of competitive resources within the time , At this time, the lock will be automatically released , Cause competitive conditions to occur .
In this case, if client Set the timer task at the end to automatically extend the lock occupation time , Can cause client Complexity and redundancy of end logic .
redisson In the process of implementation , Naturally, this problem is also taken into account ,redisson Provides a “ watchdog ” Optional features , And added lockWatchdogTimeout Configuration parameters , The watchdog thread will automatically lockWatchdogTimeout After timeout, the lock occupation time is postponed , So as to avoid the above problems .
however , Since the watchdog exists as a separate thread , Impact on performance , If it is not a special resource that is highly competitive and the processing time is not fixed , It is not recommended to enable redisson The watchdog feature of .
5.2 Multiple locks are used together — interlocking
since redisson Through multiple redis The node implements RedLock, that , If a business needs to occupy several resources at the same time , Can I use multiple locks in combination ? The answer is yes .
be based on Redis Distributed RedissonMultiLock The object will be more than one RLock Object grouping , And treat them as a lock . Every RLock Objects may belong to different Redisson example .
In this complex situation , Above “ watchdog ” It is recommended that the feature must be enabled , Because the crash of any lock state may cause the continuous suspension of all other locks or the accidental preemption of resources .
Here is redisson An example of interlocking :
public void multiLock(Integer expireTime,TimeUnit timeUnit,String ...lockKey){
RLock [] rLocks = new RLock[lockKey.length];
for(int i = 0,length = lockKey.length; i < length ;i ++){
RLock lock = redissonClient.getLock(lockKey[i]);
rLocks[i] = lock;
}
RedissonMultiLock multiLock = new RedissonMultiLock(rLocks);
multiLock.lock(expireTime,timeUnit);
logger.info("【Redisson lock】success to acquire multiLock for [ "+lockKey+" ],expire time:"+expireTime+timeUnit);
}边栏推荐
- 2022年第一季度消费金融APP用户洞察——总数达4479万人
- PCB线路板蛇形布线要注意哪些问题?
- Two methods of MySQL database login and logout
- Keras deep learning practice (12) -- facial feature point detection
- China's Industrial Software Market Research Report is released, and SCADA and MES of force control enrich the ecology of domestic industrial software
- laravel框架中 定时任务的实现
- Galaxy Kirin V10 system activation
- Introduction to deep learning and neural networks
- 如何封装调用一个库
- 明美新能源冲刺深交所:年应收账款超6亿 拟募资4.5亿
猜你喜欢

Hikvision tools manager Hikvision tools collection (including sadp, video capacity calculation and other tools) a practical tool for millions of security practitioners

How to use the low code platform of the Internet of things for picture management?

基于STM32F103ZET6库函数蜂鸣器实验

深度学习和神经网络的介绍

Good news - British software 2022 has obtained 10 invention patents!

中国工业软件市场研究报告出炉,力控SCADA、MES丰富国产工业软件生态

Technology sharing | introduction to kubernetes pod

Galaxy Kirin V10 system activation

技术分享 | kubernetes pod 简介

Space calculation of information and innovation industry in 2022
随机推荐
驾驭一切的垃圾收集器 -- G1
广发期货开户安全吗?
Cucumber自动化测试框架使用
Add in address of idea official website
云笔记到底哪家强 -- 教你搭建自己的网盘服务器
Exporting coordinates of points in TXT format in ArcGIS
New Zhongda chongci scientific and Technological Innovation Board: annual revenue of 284million and proposed fund-raising of 557million
国信证券是国企吗?在国信证券开户资金安全吗?
Hi,你有一份Code Review攻略待查收!
IDEA 官网插件地址
How to rewrite tdengine code from 0 to 1 with vscode in "technical class"
【网络研讨会】MongoDB 携手 Google Cloud 加速企业数字化创新
PostgreSQL database Wal - resource manager rmgr
破解仓储难题?WMS仓储管理系统解决方案
2022年第一季度消费金融APP用户洞察——总数达4479万人
The data synchronization tool dataX has officially supported reading and writing tdengine
网络传输是怎么工作的 -- 详解 OSI 模型
Keras deep learning practice (12) -- facial feature point detection
Market status and development prospect of resorcinol derivatives for skin products in the world in 2022
Market status and development prospect forecast of phenethyl resorcinol for skin care industry in the world in 2022