分布式锁
分布式锁
分布式锁是分布式项目中的一个重要的话题,当我们使用传统的 java 锁锁不住共享资源的时候,就要考虑分布式锁了。那么分布式锁有哪些技术方案呢?我们可以通过 redis 的分布式锁,比如 redis 的 setxnx 命令,还可以使用 redisson,第二种技术方案就是使用 zookeeper,利用的就是 zookeeper 的临时顺序节点,第三种技术方案呢就是使用数据库的主键或唯一索引来进行加锁解锁
redis 分布式锁
加锁命令:setnx key value nx ex 10s
key 可以根据自己的业务进行设置,value 可以是随机值,保证全局唯一,nx 表示这个 key 不存在的时候返回成功,否则执行失败,这样保证锁存在的时候不会再次加锁了,ex 用来设置 key 的过期时间,防止程序在运行过程中挂掉后没有释放锁导致死锁,有了过期时间后,即使程序没有主动释放锁,到了过期时间,redis 也会让这个 key 失效从而释放锁。如果当前业务加锁后 10s 没有执行完自己的业务,key 就到期了,其他线程可能会加锁成功,这时候就需要对 key 进行续期,使用的就是 watch dog,删除锁的时候要保证删的是自己的锁,也是在删锁的过程中要对 key 的 value 进行比较,一般采用 lua 脚本来进行释放锁,保证原子性
总而言之,加锁和释放锁都要保证原子性
使用 redis 做分布式锁的话一般 redis 都是读写分离的架构,而数据的复制都是异步进行的,在主从切换的时候可能导致部分数据丢失,因为 redis 保证的是最终的一致性
zookeeper 分布式锁
zookeeper 分布式锁就是利用的 zookeeper 的临时顺序节点的特性,客户端执行业务逻辑之前先在 zookeeper 中创建一个临时顺序节点,然后拿到 zookeeper 中所有的节点,如果当前节点是最小的就加锁成功,否则就需要等待。释放锁就是把自己创建的临时顺序节点删掉,之所以需要临时接点,是保证连接 zookeeper 的服务挂掉后及时的删除节点从而释放锁。
zookeeper 做分布式锁利用的是临时顺序节点,如果客户端和 zookeeper 网络发生状况可能导致错误的释放锁,而且如果节点过多,zookeeper 集群之间的数据同步也耗时
数据库分布式锁
数据库做分布式锁就是利用主键或唯一索引,保证当前业务添加一条数据后其他业务不能添加同样的数据从而保证加锁成功,释放锁就是删除数据
总结
这篇文章介绍了分布式锁的实现方式,有基于 redis 分布式锁、基于 zookeeper 实现的分布式锁和基于数据库来实现的分布式锁,真正在生产中使用的情况还是比较少的,如果用的话会使用基于这些技术封装的框架比如 Curator、Seate 等等。
版权声明: 本文为 InfoQ 作者【周杰伦本人】的原创文章。
原文链接:【http://xie.infoq.cn/article/b881c0bee8606abd89d803876】。文章转载请联系作者。
评论