etcd 以及 redis分布式锁的实现优劣比较
etcd 以及 redis分布式锁的实现优劣比较
背景介绍
在学习etcd时, 对于使用etcd实现分布式锁(使用etcd来实现一个简单的分布式锁)做了一个简单的示例, 同时也能想到和Redis实现的分布式锁相比, 基于etcd来做有什么好处呢?
技术要点
底层技术比较
我们必须要明白一件事情, 两者的底层技术有什么区别? 只有在明白底层技术的区别之后才能更进一步的探究这些区别会带来的影响. 这就是底层基础影响上层建筑的一个生动体现
Redis
大名鼎鼎的Redis, 毫无疑问, 在任何场景下Redis都是一个常用中间件, 主要的作用就是缓存
Redis 有两种部署模式: 哨兵 / 切片集群
在哨兵模式下, Redis选择了AP, 即可用性以及分区容忍性, 对于数据一致性无法提供强一致性, 只能保证尽可能达到一致性
在切片集群部署下, Redis同样选择了AP, Redis集群选择了最终一致性, 在故障转移和节点故障情况下,并不能保证每个客户端同时看到相同的数据副本。
在正常情况下,Redis 集群仍旧能够保持较高程度的一致性;但在网络分区或节点故障期间,Redis 集群的操作可能会在重新获得全局一致性之前产生窗口期,客户端可能会从还未更新的从节点读取数据。
etcd
在 CAP 定理的背景下,etcd
更倾向于选择以下两个属性:
- 一致性(C) : etcd 使用 Raft 协onsensus 算法来保证数据的强一致性。即使在网络分区的情况下,etcd 也会保证系统的线性一致性(线性一致性是强一致性的一种形式,它要求系统的操作结果如同按照全局一致的顺序执行一样)。
- 分区容忍性(P) : etcd 能够容忍网络分区。在网络分区发生时,etcd 会保证集群中的大部分节点(即大多数派)依然能够进行操作并保持一致性,这是 Raft 协议的一个特性。只有满足“多数派”存活且能彼此通信的条件下,etcd 集群才能正常工作。
在 CAP 定理的应用上,可用性(A)是 etcd 要做出妥协的属性。虽然它在正常操作中表现出非常高的可用性,但在发生网络分区或其他类型的故障,导致没有足够节点组成的多数时,etcd 会选择放弃可用性以保持数据的一致性。这意味着在极端分区情况下,它会停止服务,从而避免数据出现不一致的可能性。
因此,etcd
在 CAP 定理中选择了一致性(C)和分区容忍性(P),牺牲了部分可用性(A)。
尤其是在提供服务发现和配置服务时,一致性是非常关键的,因为客户端需要可信赖地读到最新的配置值。
分布式锁
分布式锁的几个基本特征
-
互斥性 / 安全性
绝不允许多个client同时获得锁
-
受限存活
在实现分布式锁的过程中要考虑到 client 可能会出现 crash 或者网络分区,你需要原子申请分布式锁及设置锁的自动过期时间,通过过期、超时等机制自动释放锁,避免出现死锁,导致业务中断。
-
高性能 / 高可用
加锁、释放锁的过程性能开销要尽量低,同时要保证高可用,确保业务不会出现中断。
总结
如果业务上对于分布式锁的要求非常严格:
- 在任何情况下都不允许存在多个实例获取到锁, 哪怕没有实例获取到锁
- 同时对于性能(并发量)的要求不太高
那么etcd / zk 是非常适合此场景的.
如果业务上对于分布式锁的要求稍微宽松一些:
- 业务上存在兜底的幂等处理
- 对于性能的要求高于一致性要求
那么大可以使用Redis.