当前位置:网站首页>Redis distributed lock
Redis distributed lock
2022-07-01 16:47:00 【BugMaker-shen】
List of articles
One 、 Distributed lock concept
With the needs of business development , The system deployed by the original single machine is evolved into a distributed cluster system , Due to multithreading in distributed system 、 Multi process and distributed on different machines , This will invalidate the concurrent control lock policy in the case of the original stand-alone deployment , pure Java API It doesn't provide the ability of distributed locks . In order to solve this problem, we need a kind of cross JVM To control the access of shared resources , This is the problem of distributed lock !
To put it more popularly , After locking in the cluster , No matter which machine is currently operating , All machines will recognize and wait , Other operations can only be carried out after the lock is released , This is the distributed lock , It works in all clusters
The mainstream implementation of distributed lock :
- Implementation of distributed lock based on Database
- Cache based (Redis etc. )
- be based on Zookeeper
Every distributed lock solution has its own advantages and disadvantages , among redis The highest performance zookeeper Highest reliability
Two 、 Use setnx Implementation lock
set stu:1:info “OK” nx px 10000
EX second : Set the expiration time of the key to second second ,,SET key value EX second The effect is equivalent to SETEX key second value
PX millisecond : Set the expiration time of the key to millisecond millisecond ,SET key value PX millisecond The effect is equivalent to PSETEX key millisecond value
NX : Only if the bond doesn't exist , To set the key ,SET key value NX The effect is equivalent to SETNX key value
XX : Only if the bond already exists , To set the key
- Multiple clients acquire locks at the same time (setnx)
- To be successful , Execute business logic ( from db get data , Put into cache ), Execute complete release lock (del)
- The failed client will wait for retry
use setnx and del Add and release locks
In a general way , We need to set an expiration time for the lock to prevent it from being occupied for a long time
Here's the problem : Locking and setting expiration time are two operations , Instead of operating at the same time , If something abnormal happens after locking , You can't set the expiration time . We can Set the expiration time while locking
3、 ... and 、 Write code to test distributed locks
1. Use Java Code testing distributed locks
First, in the redis Set in num The value of is 0, To write Java Code to test
What the code below does is : Get the lock num++, And release the lock ; If you don't get it 0.1 Get it back in seconds
restart , Service cluster , Pass the gateway stress test :ab -n 5000 -c 100 http://192.168.140.1:8080/test/testLock
see redis in num Value
problem : setnx Just got the lock , Exception in business logic , Causes the lock to fail to release
solve : Set expiration time , Automatic release lock
2. Optimize the lock expiration time
There are two ways to set the expiration time :
- The first thing to think about is through expire Set expiration time ( Lacking atomicity : If in setnx and expire And Exception occurred between , The lock doesn't release either )
- stay set Specify the expiration time at the same time ( recommend )
Set the expiration time in the code :
problem : May release locks on other servers
If the execution time of business logic is 7s, The execution process is as follows :
- index1 Business logic is not finished ,3 Seconds later, the lock is released automatically
- index2 Get lock , Execute business logic ,3 Seconds later, the lock is released automatically
- index3 Get lock , Execute business logic
- index1 Business logic execution complete , Start calling del Release the lock , What's released is index3 Lock of , Lead to index3 Our business only performs 1s I'll be released by someone else .
In the end, it's the case of no lock
a Stuck during operation , Cause the lock to automatically release after timeout ; After release ,b Grab the lock and operate ; here a Operation is completed , Release the lock manually , That's all. b My lock has been released ,b Releasing the lock again will report an error
solve : setnx When you get the lock , Set a specified unique value ( for example :uuid); Get this before release It's worth , Judge if it's your own lock
Four 、 Give optimization lock Set up UUID Error proofing
5、 ... and 、 Use LUA Scripts guarantee atomicity of deletion
Use lock Of uuid It can relieve the thread from releasing other locks to a certain extent , But this situation cannot be completely solved . Because it's more uuid And delete lock It's not atomic
problem : a Compare uuid After the adoption of , When the lock expires, it will be released automatically ,b Re lock ,a At this time, it will be released manually b Lock of , There is still a problem
solve : Use LUA Scripts guarantee atomicity of deletion
LUA Script :
Will be complex or multi-step redis operation , Write it as a script , Submit to redis perform , Reduce repeated connections redis The number of times , Lifting performance
LUA The script is similar to redis Business , It has certain atomicity , Will not be interrupted by other orders , You can do some redis transactional
@GetMapping("testLockLua")
public void testLockLua() {
//1 Make a statement uuid , Will be as a value Put in our key In the corresponding value
String uuid = UUID.randomUUID().toString();
//2 Define a lock :lua Scripts can use the same lock , To delete !
String skuId = "25"; // visit skuId by 25 No 100008348542
String locKey = "lock:" + skuId; // What's locked is the data of each commodity
// 3 Get the lock
Boolean lock = redisTemplate.opsForValue().setIfAbsent(locKey, uuid, 3, TimeUnit.SECONDS);
// The first one is : lock Don't write any code between the expiration time .
// redisTemplate.expire("lock",10, TimeUnit.SECONDS);// Set expiration time
// If true
if (lock) {
// The business logic of execution begins
// Get the num data
Object value = redisTemplate.opsForValue().get("num");
// If it's empty, return to
if (StringUtils.isEmpty(value)) {
return;
}
// Not empty If something goes wrong here ! that delete The deletion failed ! That is to say, the lock always exists !
int num = Integer.parseInt(value + "");
// send num Every time +1 Put into cache
redisTemplate.opsForValue().set("num", String.valueOf(++num));
/* Use lua Script to lock */
// Definition lua Script : Judge and delete at the same time
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
// Use redis perform lua perform
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(script);
// Set the return value type by Long
// Because when you delete judgment , Back to 0, Encapsulate it as a data type . If it's not encapsulated, it will return by default String type ,
// So return the string and 0 There will be mistakes .
redisScript.setResultType(Long.class);
// The first is the execution script Script , The second thing that needs to be judged key, The third is key The corresponding value .
redisTemplate.execute(redisScript, Arrays.asList(locKey), uuid);
} else {
// Other threads wait
try {
// sleep
Thread.sleep(1000);
// When I wake up , Calling method .
testLockLua();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
To ensure that distributed locks are available , We should at least ensure that the implementation of the lock meets the following four conditions at the same time :
- Mutual exclusivity ; At any moment , Only one client can hold the lock
- A deadlock will not occur ; Even if a client crashes while holding a lock without actively unlocking it , It can also ensure that other clients can be locked later ( Set up lock The expiration time of )
- He who breaks the bell must tie the bell ; Lock and unlock must be the same client , The client can't unlock the lock added by others ( Use LUA Scripts and uuid)
- Locking and unlocking must be atomic ( Use LUA Script )
边栏推荐
- Is the programmer's career really short?
- Are you still using charged document management tools? I have a better choice! Completely free
- Rhcsa Road
- FPN网络详解
- Preliminary study on golang crawler framework
- Apple's self-developed baseband chip failed again, which shows Huawei Hisilicon's technological leadership
- 今天14:00 | 港大、北航、耶鲁、清华、加大等15位ICLR一作讲者精彩继续!
- sql刷题1050. 合作过至少三次的演员和导演
- SQL question brushing 627 Change gender
- Borui data integrated intelligent observable platform was selected into the "Yunyuan production catalogue" of China Academy of communications in 2022
猜你喜欢
广东用电量大跌,说明高新技术产业替代高能耗产业已取得初步成果
Template engine velocity Foundation
游戏行业安全选择游戏盾,效果怎么样?
How to cancel automatic search and install device drivers for laptops
OJ questions related to complexity (leetcode, C language, complexity, vanishing numbers, rotating array)
Today, at 14:00, 15 ICLR speakers from Hong Kong University, Beihang, Yale, Tsinghua University, Canada, etc. continue!
嗨 FUN 一夏,与 StarRocks 一起玩转 SQL Planner!
SystemVerilog-结构体(二)
How to restore the system of Sony laptop
數據庫系統原理與應用教程(006)—— 編譯安裝 MySQL5.7(Linux 環境)
随机推荐
数据库系统原理与应用教程(003)—— MySQL 安装与配置:手工配置 MySQL(windows 环境)
Building blocks for domestic databases, stonedb integrated real-time HTAP database is officially open source!
数据库系统原理与应用教程(002)—— MySQL 安装与配置:MySQL 软件的卸载(windows 环境)
Is it reliable to open an account on flush with mobile phones? Is there any potential safety hazard
嗨 FUN 一夏,与 StarRocks 一起玩转 SQL Planner!
判断二叉树是否为二叉搜索树
[live broadcast appointment] database obcp certification comprehensive upgrade open class
SystemVerilog-结构体(二)
虚拟串口模拟器和串口调试助手使用教程「建议收藏」
数据库系统原理与应用教程(001)—— MySQL 安装与配置:MySQL 软件的安装(windows 环境)
瑞典公布决定排除华为5G设备,但是华为已成功找到新出路
Detailed explanation of activity life cycle and startup mode
sql刷题586. 订单最多的客户
芯片供应转向过剩,中国芯片日产增加至10亿,国外芯片将更难受
Leetcode 216 combined summation III -- backtracking method
C語言輸入/輸出流和文件操作
Tutorial on the principle and application of database system (003) -- MySQL installation and configuration: manually configure MySQL (Windows Environment)
Rhcsa Road
数据库系统原理与应用教程(004)—— MySQL 安装与配置:重置 MySQL 登录密码(windows 环境)
Ring iron pronunciation, dynamic and noiseless, strong and brilliant, magic wave hifiair Bluetooth headset evaluation