当前位置:网站首页>Redis distributed lock principle and its implementation with PHP (1)
Redis distributed lock principle and its implementation with PHP (1)
2022-07-05 15:05:00 【Back end regular developers】
List of articles
One 、 The role of distributed locks :
redis Write without locking function , To prevent multiple processes from performing an operation at the same time , Unexpected results ,so… Customize the locking function when inserting and updating the cache .
Two 、Redis Of NX Suffix command
Redis There's a series of orders , It is characterized by NX ending ,NX It can be understood as NOT EXISTS( non-existent ),SETNX command (SET IF NOT EXISTS) It can be understood that if it does not exist, insert ,Redis The implementation of distributed locks mainly uses SETNX command .
3、 ... and 、 Realization principle
Judge before the process requests to perform an operation , Whether the locking is successful , Successful locking allows the next operation ;
If it doesn't work , Then judge the value of the lock ( Time stamp ) Is greater than the current time , If greater than the current time , Then the lock acquisition fails, and the next operation is not allowed ;
If the value of the lock ( Time stamp ) Less than the current time , also GETSET The old value of the lock obtained by the command is still less than the current time , If the lock is obtained successfully, the next operation is allowed ;
If the value of the lock ( Time stamp ) Less than the current time , also GETSET The old value of the lock obtained by the command is greater than the current time , Then the lock acquisition fails, and the next operation is not allowed ;
Four 、$redis->setnx() Set lock
$expire = 10;// The period of validity 10 second
$key = 'lock';//key
$value = time() + $expire;// Value of lock = Unix Time stamp + The validity of the lock
$lock = $redis->setnx($key, $value);
// Judge whether the lock is successful , If successful, perform the next operation
if(!empty($lock))
{
// Next operation ...
}
If you return 1 , It means that the current process obtains the lock , And get the current insert / Update cached operation permissions .
If you return 0, Indicates that the lock has been acquired by another process , This is a process that can return results or wait for the current lock to fail before requesting .
5、 ... and 、 Solve the deadlock
If only SETNX Command to set the lock , If the process holding the lock crashes or the deletion of the lock fails , Other processes will not be able to acquire locks , It's a big problem .
The solution is to obtain the value of the lock while obtaining the lock fails , And compare the value with the current time , If the value is less than the current time, the lock will expire , The process can be applied Redis Of DEL Command to delete the lock .
$expire = 10;// The period of validity 10 second
$key = 'lock';//key
$value = time() + $expire;// Value of lock = Unix Time stamp + The validity of the lock
$status = true;
while($status)
{
$lock = $redis->setnx($key, $value);
if(empty($lock))
{
$value = $redis->get($key);
if($value < time())
{
$redis->del($key);
}
}else{
$status = false;
// Next operation ....
}
}
however , Use... Simply and roughly DEL Command to delete the lock again SETNX Command locking can also cause problems . such as , process 1 Crash after obtaining lock or failed to delete lock , And then the process 2 A lock is detected when it has expired , use DEL Command to delete the lock and use SETNX Command set lock , process 3 Lock expiration was also detected , Also used DEL The command delete lock is also used SETNX The command sets the lock , And then the process 2 And processes 3 The lock is also obtained . It's a big problem !
To solve this problem , It's used here Redis Of GETSET command ,GETSET The command returns the old value of the lock while setting a new value for the lock , So this is taking advantage of GETSET Command to get and assign properties at the same time , During this period, other processes cannot modify the value of the lock .
for example :
process 1 The operation timed out after obtaining the lock / collapse / Failed to delete lock ,
process 2 Detected that the lock already exists , However, the value of the lock obtained is compared with the current time, and it is found that the lock has expired ,
process 2 adopt GETSET The command assigns a new value to the lock , And get the old value of the lock , Compare the old value of the lock with the current time again , If the old value of the lock is still less than the current time , And then the process 2 You can ignore the process 1 I left the waste lock for the next operation .
process 2 After completing the next operation, you should delete the lock before returning , However, when deleting a lock, you can first check whether the lock has not expired , Delete before expiration , There is no need to delete locks that have expired , Because it is very likely that other processes have gone to acquire the lock when they detect that the lock has expired .
The point here is , If there are other processes in the process 2 Lock acquired before , So the process 2 Will fail to acquire the lock , But the process 2 In use GETSET When getting the old value of the lock, the lock is also given a new value , Rewrites the timeout value given to the lock by other processes . Seeing this, you may have questions , process 2 How can you change the value of a lock without obtaining it ? Yes , process 2 Changed the original value of the lock , But the impact of this small time error can be ignored .
Here are Redis Realize the integrity of distributed locks PHP Code :
<?php
/** * Realization Redis Distribution of the lock */
$key = 'test'; // To update the cache of information KEY
$lockKey = 'lock:'.$key; // Set lock KEY
$lockExpire = 10; // Set the validity of the lock to 10 second
// Get cache information
$result = $redis->get($key);
// Determine whether there is data in the cache
if(empty($result))
{
$status = TRUE;
while ($status)
{
// Set the lock value to the current timestamp + The period of validity
$lockValue = time() + $lockExpire;
/** * Create a lock * Try to use $lockKey by key Create a cache ,value The value is the current timestamp * because setnx() The function only exists when it does not exist key Cache will be created successfully * therefore , This function can be used to determine whether the current operation has been executed by other processes * @var [type] */
$lock = $redis->setnx($lockKey, $lockValue);
/** * The operation can be carried out when one of the two conditions is met * 1、 The lock was created successfully in the previous step ; * 2、 1) Judge the value of the lock ( Time stamp ) Whether it is less than the current time $redis->get() * 2) At the same time, set a new value for the lock successfully $redis->getset() */
if(!empty($lock) || ($redis->get($lockKey) < time() && $redis->getSet($lockKey, $lockValue) < time() ))
{
// Set the lifetime of the lock
$redis->expire($lockKey, $lockExpire);
//******************************
// Insert here 、 Update cache operation ...
//******************************
// Delete the lock after the above procedure
// Check whether the lock has expired , There is no need to delete expired locks
if($redis->ttl($lockKey))
$redis->del($lockKey);
$status = FALSE;
}else{
/** * If there is a valid lock, handle it accordingly * Wait for the current operation to complete before executing this request * Go straight back to */
sleep(2);// wait for 2 Try the operation again in seconds
}
}
}
Used to implement distributed locks Redis Command Introduction :
setnx(key, value)
take key The value of the set value, If and only if key non-existent .
If a given key Already exist , be SETNX Don't do anything .
SETNX yes ”SET if Not eXists”( If it doesn't exist , be SET) Abbreviation .
Return value :
Set up the success , return 1.
Setup failed , return 0.
get(key)
return key The string value associated .
If key If it does not exist, it returns a special value nil.
If key The stored value is not of string type , Return an error , because GET Can only be used to process string values .
Return value :
key Value .
If key non-existent , return nil.
getset(key, value)
Will be given key The value of the set value, And back to key The old value .
When key When it exists but is not a string type , Return an error .
Return value :
Return to a given key The old value (old value).
When key When there is no old value , return nil.
expire(key, seconds)
For a given key Set the lifetime .
When key expires , It will be automatically deleted .
stay Redis in , With time to live key It's called “ Volatile ”(volatile).
Below 2.1.3 Version of Redis in , The existing lifetime cannot be overwritten .
from 2.1.3 Version start ,key The lifetime of can be updated , Can also be PERSIST Command to remove .( For details, see http://redis.io/topics/expire).
Return value :
Set successfully returned 1.
When key Does not exist or cannot be for key When setting the lifetime ( For example, below 2.1.3 You try to update key Survival time ), return 0.
ttl(key)
Return to a given key The remaining lifetime of (time to live)( In seconds ).
Return value :
key The remaining lifetime of ( In seconds ).
When key When the lifetime does not exist or is not set , return -1 .
del(key)
Remove the given one or more key.
Return value :
Removed key The number of .
from :https://zhuanlan.zhihu.com/p/363418902
边栏推荐
- 可视化任务编排&拖拉拽 | Scaleph 基于 Apache SeaTunnel的数据集成
- Jmeter性能测试:ServerAgent资源监控
- DVWA range clearance tutorial
- 我这边同时采集多个oracle表,采集一会以后,会报oracle的oga内存超出,大家有没有遇到的?
- 729. 我的日程安排表 I :「模拟」&「线段树(动态开点)」&「分块 + 位运算(分桶)」
- 漫画:程序员不是修电脑的!
- IPv6与IPv4的区别 网信办等三部推进IPv6规模部署
- How to open an account of qiniu securities? Is it safe to open an account?
- Live broadcast preview | how to implement Devops with automatic tools (welfare at the end of the article)
- Your childhood happiness was contracted by it
猜你喜欢
qt creater断点调试程序详解
Photoshop plug-in action related concepts actionlist actiondescriptor actionlist action execution load call delete PS plug-in development
There is a powerful and good-looking language bird editor, which is better than typora and developed by Alibaba
【数组和进阶指针经典笔试题12道】这些题,满足你对数组和指针的所有幻想,come on !
Interpretation of Apache linkage parameters in computing middleware
MySQL----函数
Huawei Hubble incarnation hard technology IPO harvester
B站做短视频,学抖音死,学YouTube生?
Stop B makes short videos, learns Tiktok to die, learns YouTube to live?
729. My schedule I: "simulation" & "line segment tree (dynamic open point) &" block + bit operation (bucket Division) "
随机推荐
面试突击62:group by 有哪些注意事项?
Under the crisis of enterprise development, is digital transformation the future savior of enterprises
STM32+BH1750光敏传感器获取光照强度
GPS原始坐标转百度地图坐标(纯C代码)
通过npm 或者 yarn安装依赖时 报错 出现乱码解决方式
超级哇塞的快排,你值得学会!
CPU design related notes
数据库学习——数据库安全性
I want to inquire about how to ensure data consistency when a MySQL transaction updates multiple tables?
PHP high concurrency and large traffic solution (PHP interview theory question)
Garbage collection mechanism of PHP (theoretical questions of PHP interview)
Fr exercise topic - simple question
Two Bi development, more than 3000 reports? How to do it?
美团优选管理层变动:老将刘薇调岗,前阿里高管加盟
【C 题集】of Ⅷ
Where is the operation of convertible bond renewal? Is it safer and more reliable to open an account
How to paste the contents copied by the computer into mobaxterm? How to copy and paste
超越PaLM!北大碩士提出DiVeRSe,全面刷新NLP推理排行榜
我想咨询一下,mysql一个事务对于多张表的更新,怎么保证数据一致性的?
Cartoon: what are the attributes of a good programmer?