当前位置:首页 > 问答 > 正文

面试时老被问分布式锁用Redis还是Zookeeper到底哪个靠谱点啊

(来源:掘金社区《分布式锁用Redis还是Zookeeper?这一次就彻底搞明白!》)面试的时候,面试官老爱问这个问题,其实是想看看你对不同技术选型的理解深度,以及你是不是只会死记硬背,有没有在实际项目中思考过权衡和取舍,你别慌,这事儿没那么玄乎,咱们就把它当成“出门远足是选运动鞋还是登山靴”的问题来聊,关键看你要走什么路。

Redis:性能猛男,但可能“健忘”

(来源:Redis官方文档关于SETNX命令及过期时间的说明)Redis实现分布式锁,最常见的就是用SET key value NX PX timeout这个命令,NX表示只有key不存在时才设置,这就相当于抢锁;PX给锁设置一个过期时间,比如10秒,这招儿好处特别明显:!因为Redis基于内存,读写速度极快,能扛住高并发场景,你想象一下双十一秒杀,瞬间几万请求来抢锁,用Redis能迅速给出结果,吞吐量非常高。

但它有个最让人担心的点:可靠性,Redis的锁不是绝对可靠的,你设置的过期时间是个“兜底”机制,怕的就是客户端抢到锁后挂了,没法主动释放,导致锁永远不释放(死锁),但这个兜底机制本身也带来了新问题,万一你的业务逻辑执行时间超过了锁的过期时间(比如网络卡顿、Full GC导致处理慢了),锁就自动失效了,这时另一个客户端就能抢到锁,然后你的系统里就可能有两台机器同时执行业务代码,数据就乱套了。

(来源:Martin Kleppmann的经典文章《How to do distributed locking》)为了解决这个问题,有人提出了Redlock算法,它的大致思路是同时向多个独立的Redis主节点申请锁,超过半数成功才算真正拿到锁,这确实提高了安全性,但同时也让方案变复杂了,性能下降,而且业界对Redlock是否百分百安全还有争议,很多业务场景下,如果你能接受极低概率的锁失效(比如允许偶尔超卖一两件商品),或者有其它补偿机制,那么单Redis实例的简单锁,凭借其极高的性能,依然是个不错的选择,简单说,Redis锁像是那个动作麻利的短跑选手,爆发力强,但你别指望它跑马拉松还能一点差错不出。

Zookeeper:稳重可靠,但动作稍慢

(来源:ZooKeeper官方文档关于ZNode的说明)Zookeeper天生就是个为分布式协调而生的系统,它用ZNode(数据节点)来实现锁就非常自然,通常做法是创建一个临时顺序节点,所有客户端都在一个指定的目录下创建临时顺序节点,Zookeeper会保证节点编号是递增的,判断谁拿到锁的规则很简单:当前序号最小的节点获得锁,如果释放锁(比如客户端会话失效,临时节点会自动删除),就通知下一个序号最小的节点。

这种方式的好处是靠谱,它是靠会话保持的,只要你的客户端和ZooKeeper服务器的会话还活着,锁就一直归你,不存在因为超时导致的误释放问题,因为节点是顺序的,它天然就实现了公平锁,先来后到,不会饿死,最重要的是,ZooKeeper通过Zab协议保证了强一致性,锁状态在所有客户端看来都是一致的,不会出现Redis那种因为主从延迟导致的数据不一致问题。

那代价是什么呢?性能,Zookeeper每次写操作(比如创建、删除节点)都需要在集群多数节点上达成一致,这个过程比Redis基于内存的写操作要慢得多,在高并发抢锁的场景下,频繁的写操作会给Zookeeper集群带来压力,吞吐量肯定不如Redis,Zookeeper锁像是那个步伐坚定的马拉松选手,极其可靠,但你让他去冲刺百米,他可能没那么快。

到底该怎么选?看你的“场景”

面试官想听的绝不是“Zookeeper更好”或“Redis更好”这种标准答案,而是你根据场景做决策的能力。

  • 如果你追求极致性能,锁失效的短暂风险在业务上可以接受(比如做缓存防击穿,商品库存有后续校验),那么Redis是个好选择,简单高效。
  • 如果你的业务对锁的正确性要求极高,一点都不能错(比如金融交易的核心账务处理),宁愿牺牲一点性能也要保证万无一失,那么Zookeeper的强一致性和可靠性更让你安心。
  • (来源:阿里巴巴开源项目Seata的架构设计)现在还有个趋势,很多公司会采用数据库(如MySQL)的唯一索引或悲观锁来实现简单的分布式锁,虽然性能一般,但依赖少,对于锁竞争不激烈、已经有数据库依赖的系统来说,也是个朴素的解决方案。

你回答的时候可以这么说:“这个问题没有标准答案,核心是权衡,Redis性能好但可能不够安全,适合可以容忍少量冲突的场景;Zookeeper可靠性高但性能有瓶颈,适合对一致性要求苛刻的场景,在实际项目中,我们还得考虑团队的熟悉程度、现有的技术栈以及运维成本,如果系统已经用了Zookeeper做服务发现,引入它来实现锁可能更简单;如果系统完全是Redis技术栈,那引入Zookeeper就为了一个锁反而增加了复杂度。” 这样回答,既展示了你的知识面,又体现了你的思考深度,面试官会觉得你不是个死读书的人。

面试时老被问分布式锁用Redis还是Zookeeper到底哪个靠谱点啊