使用Redis实现分布式锁
分布式锁简介
分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一种锁实现。
分布式锁可以保证在分布式系统中,同一操作只被一台机器上的一个线程执行,保证共享数据的一致性。
分布式锁的设计要求
- 要是可重入锁(避免死锁)
- 要有高可用的获取锁、释放锁功能
- 获取锁、释放锁的性能要好
使用redis实现分布式锁的思路
(1)setnx(String key,String value)
若返回1,说明设置成功,获取到锁;
若返回0,说明设置失败,已经有了这个key,说明其它线程持有锁,重试。
重试需要设置一个超时时间|重试次数,不能一直尝试、阻塞在这里,达到超时时间|指定次数后还未获取到锁就放弃,实现高可用。
重试可以用while(true){ }来实现,如果未获取到锁,Thread.sleep()沉睡1s后再次执行,if(重试次数达到多少)就放弃;如果获取到锁(返回1),结束循环,继续往下执行。
value可以是任意的,但为了可读性、方便调试|维护,哪个机器的哪个线程的哪个方法要获取锁,一般就以 ip|主机名+线程名+方法名 拼接为标识符,作为value。
(2)expire(String key, int seconds)
获取到锁(返回1)后,还需要用设置生存期,如果在多少秒内没有完成,比如发生机器故障、网络故障等,键值对过期,释放锁,实现高可用。
(3)del(String key)
完成业务后需要释放锁。释放锁有2种方式:del删除key,或者expire将有效期设置为0(马上过期)。
在执行业务过程中,如果发生异常,不能继续往下执行,也应该马上释放锁。
上述方法是jedis中的方法,如果使用spring data redis,对应的方法如下
Boolean redisTemplate.opsForValue().setIfAbsent(key,value) //absent,缺席、不存在。返回的是布尔值
redisTemplate.expire(key,2,TimeUnit.MINUTES) //有效期
Boolean redisTemplate.opsForValue().setIfAbsent(key,value,2,TimeUnit.MINUTES) //上面2句代码可以写成一句
redisTemplate.delete(key) //删除key
相关文章
- Redis分布式锁的五大演进攻略
- Redis几个认识误区(转)
- DOCKER简明教程 : 通过容器连接REDIS数据库
- 运维基础之Redis(1)简介、安装、使用
- Redis API的原子性分析
- 直播兴起的军功章上也有你的一半——Redis实践及在直播行业的应用
- Atitit it计算机应用体系图 大数据 爬虫 非结构数据 nosql redis mongodb 分布式存储 es搜索 可视化 多媒体与office 19.1. 14.3 计
- Lua与Redis的那些事儿
- 【最详细】最新最全Redis面试大全(50道)
- 〖Python 数据库开发实战 - Python与Redis交互篇⑧〗- 利用 redis-py 实现缓存观众投票数据信息案例
- Python Flask框架学习30:redis操作/配置静态文件路径
- Springboot系列之Shiro、JWT、Redis 进行认证鉴权
- Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析&Redis分布式锁的正确使用姿势!...
- Redis源码之ZipList压缩列表
- c# redis系列二
- redis_02 _ 数据结构:快速的Redis有哪些慢操作?
- redis的主从复制,读写分离,主从切换
- Redis-3.2.0集群配置(redis cluster)
- Redis进阶学习10---redis最佳实践
- 03-Redis客户端连接Redis服务器(redis.conf 文件配置没有生效导致redis运行报错Error: Connection reset by peer)
- 【缓存中间件】redis 支持的数据类型
- redis单线程原理___Redis为何那么快-----底层原理浅析
- Redis_23_Redis实现分布式锁
- 【redis源码分析】Redis Sentinel 是如何实际解决分布式共识问题的
- 使用Redis工具自动部署cluster集群(十三)