Redis实现分布式锁-阿里云开发者社区

开发者社区> 数据库> 正文
登录阅读全文

Redis实现分布式锁

简介: 系列文章基于Redis2.8版本1:Redis学习资料收集2:Redis基础数据结构3:Redis实现分布式锁 官方实现 https://redis.io/topics/distlock 官方实现--翻译中文 http://www.redis.cn/topics/distlock.html 声明:看了很多文章,大多数文章都是摘取了官方文档,或者在上面进行加工,所以建议大家可以看上面的参考文档。

系列文章基于Redis2.8版本
1:Redis学习资料收集
2:Redis基础数据结构
3:Redis实现分布式锁

官方实现
https://redis.io/topics/distlock

官方实现--翻译中文
http://www.redis.cn/topics/distlock.html

声明:看了很多文章,大多数文章都是摘取了官方文档,或者在上面进行加工,所以建议大家可以看上面的参考文档。

3.1 为什么需要分布式锁

系统里面有一些资源是竞争保护性资源。例如抢购活动中的商品库存。

然而我们后台系统一般会使用负载均衡,微服务等。会导致有多个JVM实例,所以我们Java的同步代码块synchronized,以及java.util.concurrent.locks包下常用的方法就不能满足需求。

解决办法:

1:基于数据库的乐观锁,和排它锁。

2:基于Zookeeper创建临时节点。

3:基于Redis实现。

3.2 实现分布式锁要实现的关键点

  1. 互斥:只能有一个客户端拥有所。

  2. 不会发生死锁:持有锁的客户端异常,超时,能正确释放锁。

  3. 容错性:只有大部分Redis节点正常运行,客户端就应该可以正常的加锁,解锁。

3.3 通过Redis实现(单个Redis实例)

3.3.1 获取锁
SET lock_key lock_value NX PX timeout

lock_key:我们获取的锁

lock_value:锁的值

NX:保证只有键不存在的时候插入

PX timeout:设置键的过期毫秒数
3.3.2 解锁

解锁通过Lua脚本实现

因为get del 不能保证语义的原子性

    if redis.call("get",KEYS[1]) == ARGV[1] then
        return redis.call("del",KEYS[1])
    else
        return 0
    end

4 Java代码实现

5 其他问题

锁的可重入性怎么实现

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: