背景
基于前面两篇文章,了解了redis 锁和zk 锁实现分布式锁的原理和方式,但是在实践中,如何去选择呢?
在分布式场景下,分布式CAP 定理告诉我们,任何一个分布式系统都无法满足C(Consistency) 一致性,A(Availability) 可用性,P(Partition tolerance) 分区容错性,最多只能同时满足两项;
分布式锁最终理想结果是什么?
1. 可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行。
2. 这把锁要是一把可重入锁(避免死锁)
3. 这把锁最好是一把阻塞锁(根据业务需求考虑要不要这条)
4. 有高可用的获取锁和释放锁功能
5. 获取锁和释放锁的性能要好
Zk 分布式锁 和Redis 分布式锁的对比
ZK 锁的优缺点
优点:
1. 实现简单
2. 有效避免死锁问题
3. 解决锁重入问题
4. 解决单点问题,可靠性比较高
缺点:
1. 性能差,zk 实现分布式锁的原理是基于创建临时节点实现的,并且所有的增删改都是在header 节点进行实现的,在高并发环境下,频繁创建删除节点,性能没有基于缓存快
2. 使用Zookeeper也有可能带来并发问题,只是并不常见而已。考虑这样的情况,由于网络抖动,客户端可ZK集群的session连接断了,那么zk以为客户端挂了,就会删除临时节点,这时候其他客户端就可以获取到分布式锁了。就可能产生并发问题。这个问题不常见是因为zk有重试机制,一旦zk集群检测不到客户端的心跳,就会重试,Curator客户端支持多种重试策略。多次重试之后还不行的话才会删除临时节点。
Redis 分布式锁的优缺点
优点:
1. 性能好
2. 使用方便
缺点:
1. 集群环境下,master 宕机后,数据一致性无法保证
性能对比
redis 分布式锁> zk 分布式锁
可靠性
zk 分布式锁> redis 分布式锁
如何选择?
上面几种方式,哪种方式都无法做到完美。就像CAP一样,在复杂性、可靠性、性能等方面无法同时满足,所以,根据不同的应用场景选择最适合自己的方式。