0


Zookeeper与Redis 对比

1. 为什么使用分布式锁?

    使用分布式锁的目的,是为了保证同一时间只有一个 JVM 进程可以对共享资源进行操作。

根据锁的用途可以细分为以下两类:

    1、 允许多个客户端操作共享资源,我们称为共享锁。

           这种锁的一般是对共享资源具有幂等性操作的场景,主要是为了避免重复操作共享                 资源频繁加锁带来的性能开销。

    2、 只允许一个客户端操作共享资源,我们成为排他锁。

           这种锁一般是用在对共享资源操作具有非幂等性操作的场景,也就是需要保证在同                 一时刻只有一个进程或者线程能够访问这个共享资源。

2. 目前实现分布式锁最常用的中间件是 Redis和Zookeeper

**a、第一种,Redis 可以通过两种方式来实现 **

            i. 利用 Redis 提供的`SET key value NX PX milliseconds `指令,这个指令是设                           置一个 key-value,如果 key 已经存在,则返回 0,否则返回 1, 我们基于这个                     返回值来判断锁的占用情况从而实现分布式锁。

            ii. 基于 Redission 客户端来实现分布式锁,Redisson 提供了分布式锁的封装方                          法,我们只需要调用 api 中的`lock()`和`unlock()`方法。它帮我们封装锁实现                      的细节和复杂度

                            1. redisson 所有指令都通过 lua 脚本执行并支持 lua 脚本原子性执行

                            2. redisson 中有一个 watchdog 的概念,翻译过来就是看门狗,它会在                                      你获取锁之后,每隔 10 秒帮你把 key 的超时时间设为 30s,就算一                                        直持有锁也不会出现 key 过期了。

                                “看门狗”的逻辑保证了没有死锁发生。

b. 第二种,基于 ZK 实现分布式锁的落地方案

** **Zookeeper 实现分布式锁的方法比较多,我们可以使用有序节点来实现。

             i. 每个线程或进程在 Zookeeper 上的`/lock`目录下创建一个临时有序的节点表示                        去抢占锁,所有创建的节点会按照先后顺序生成一个带有序编号的 节点。

             ii. 线程创建节点后,获取/lock 节点下的所有子节点,判断当前线程创建的节点是                       否是所有的节点的序号最小的。

             iii. 如果当前线程创建的节点是所有节点序号最小的节点,则认为获取锁成功。

             iv. 如果当前线程创建的节点不是所有节点序号最小的节点,则对节点序号的前一                       个节点添加一个事件监听,当前一个被监听的节点释放锁之后,触发回调通                            知,从而再次去尝试抢占锁。

3. 两种方案都有各自的优缺点

对于 redis 的分布式锁而言,它有以下缺点:

1、它获取锁的方式简单粗暴,如果获取不到锁,会不断尝试获取锁,比较消耗性能。

2、Redis 是 AP 模型,在集群模式中由于数据的一致性会导致锁出现问题,即便使用 Redlock 算法来实现,在某些复杂场景下,也无法保证其实现 100%的可靠性。 不过在 实际开发中使用 Redis 实现分布式锁还是比较常见,而且大部分场情况下不会遇 到”极端 复杂的场景“,更重要的是 Redis 性能很高,在高并发场景中比较合适。

补充:

    明显AP结构选择了高可用和分区容错性,此时,那个失去联系的节点依然可以向系统提供服务,不过它的数据就不能保证是同步的了(失去了C属性)。Eureka就是一个AP架构的例子,当Eureka客户端心跳消失的时候,那Eureka服务端就会启动自我保护机制,不会剔除该EurekaClient客户端的服务,依然可以提供需求;

对于 zk 分布式锁而言

1、zookeeper 天生设计定位就是分布式协调,强一致性。锁的模型健壮、简单易用、 适合 做分布式锁。

2、 如果获取不到锁,只需要添加一个监听器就可以了,不用一直轮询,性能消耗较小。 如 果要在两者之间做选择,就个人而言的话,比较推崇 ZK 实现的锁,因为对于分布 式 锁言,它应该符合 CP 模型,但是 Redis 是 AP 模型,所以在这个点上,Zookeeper 会更 加合适。

标签: java

本文转载自: https://blog.csdn.net/qq_43276879/article/details/132201098
版权归原作者 一只快乐的蓝巴德 所有, 如有侵权,请联系我们删除。

“Zookeeper与Redis 对比”的评论:

还没有评论