怎样用redis实现分布式锁
引子
redis作为一个强大的key/value数据库。事实上还能够用来实现轻量级的分布式锁。
1.实现方案1
最早官方在SETNX命令页给了一个实现:
acquire lock: SETNX lock.foo <current Unix time + lock timeout + 1>
release lock: DEL lock.foo
acquire lock when time expired: GETSET lock.foo <current Unix timestamp + lock timeout + 1>
只是这个方法有漏洞。就是release lock用的DEL命令不支持cas删除(delete if current value equals old value)。这样忽略race condition将会出现故障:
A client will try to release the lock after the expire time deleting the key created by another client that
acquired the lock later.
2.实现方案2
官方在SETNX命令页介绍了新的方案:SET
command + Lua script:
Starting with Redis 2.6.12 it is possible to create a much simpler locking primitive using the SET command
to acquire the lock, and a simple Lua script to release the lock. The pattern is documented in the SET command
page.
The old SETNX based
pattern is documented below for historical reasons.
该方案有2个优化:
(1)SET 命令能够设置key过期时间:SET key value [EX seconds] [PX milliseconds] [NX|XX]
The lock will be auto-released after the expire time is reached.
(2)使用Lua脚本实现cas删除(详见SET命令页)
It is possible to make this system more robust modifying the unlock schema as follows:
- Instead of setting a fixed string, set a non-guessable large random string, called token.
- Instead of releasing the lock with DEL,
send a script that only removes the key if the value matches.
最新文章
- Linux基础 - scp免密码登陆进行远程文件同步
- CentOS6配置国内yum源
- ios 按钮点击无反应
- Direct2D教程(外篇)环境配置
- CentOS 6.5下源码安装MySQL 5.6
- 学习jsp(1)
- [SQL]公交新路问题
- linux-搜索
- Lombok(1.14.8) - @NonNull
- AngularJS Boostrap Pagination Sample
- zxing 生成二维码
- Mob短信验证的配置的解释
- 记一次内存泄漏DUMP分析
- sql的ExecuteScalar(),ExecuteNonQuery()
- 初识Selenium(一)
- Erlang cowboy 入门参考之现代Web的发展历史
- mysql-列属性
- 深度学习之Batch Normalization
- Mockito框架入门教程(二)
- CentOS6.5搭建OpenVas完全搭建手册(搭建过程总结及小记)