高频面试题实现分布式锁中,zookeeper和Redis哪种更好?

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 一位6年工作经验的小伙伴,在某厂面试时被问到“实现分布式锁,Zookeeper 和 Redis 哪种更好?“,这其实是一个开放性的问题。并没有标准答案。那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。

一位6年工作经验的小伙伴,在某厂面试时被问到“实现分布式锁,Zookeeper 和 Redis 哪种更好?“,这其实是一个开放性的问题。并没有标准答案。那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。


另外,我把往期分享的视频全部整理成一份500页的PDF面试题解析配套文档,希望能够以此来提高各位粉丝的通过率,

3c49a408152941fb99f810c374920902.gif

如何获取? :

扫描文章底部二维码领取!

1、背景介绍

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

38bb2e92253eda98f112f7c503b2fe02.jpg

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


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


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


2、只允许一个客户端操作共享资源,我们称为排他锁。这种锁一般是用在对共享资源操作具有非幂等性操作的场景,也就是需要保证在同一时刻只有一个进程或者线程能够访问这个共享资源。

2、实现方案

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


首先来看Redis的实现方案,它可以通过两种方式来实现


1. 利用 Redis 提供的 SET key value NX PX milliseconds 指令,

cc04adee0e520e08630976551cf71d24.jpg

这个指令是设置一个Key-Value,如果 Key 已经存在,则返回 0,否则返回 1,我们基于这个返回值来判断锁的占用情况从而实现分布式锁。


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


Redission 所有指令都通过 Lua 脚本执行并支持 Lua 脚本原子性执行, Redission 中有一个 WatchDog 的概念,翻译过来就是看门狗,它会在你获取锁之后,每隔 10 秒帮你把 Key 的超时时间设为 30s,就算一直持有锁也不会出现Key 过期了。“看门狗”的逻辑保证了没有死锁发生。


然后,基于 ZooKeeper 实现分布式锁的落地方案


Zookeeper 实现分布式锁的方法比较多。我推荐使用有序节点来实现,来看这个图,

7493863291afc945a4c2c04bc58e3885.jpg

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


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


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


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

3、两者对比

接下来,咱们来对比一下这两种方案:


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

d8faf1debbc326bc01f1fc55dadb4719.jpg

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


2、Redis 是 AP 模型,在集群模式中由于数据的一致性会导致锁出现问题,即便使用 Redlock 算法来实现,在某些复杂场景下,也无法保证其实现 100%的可靠性。


不过在实际开发中使用 Redis 实现分布式锁还是比较常见,而且大部分场情况下不会遇到”极端复杂的场景“,更重要的是 Redis 性能很高,在高并发场景中比较合适。


对于Zookeeper 分布式锁而言:

c890908fd7495eb63ef44afa272b773b.jpg

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


2、如果获取不到锁,只需要添加一个监听器就可以了,不用一直轮询,性能消耗较小。


如果要在两者之间做选择,就我个人而言的话,比较推崇 ZK 实现的锁,因为对于分布式锁而言,它应该符合 CP 模型,但是 Redis 是 AP 模型,所以在这个点上,Zookeeper 会更加合适。


最后,我把往期分享的视频全部整理成了1份20W字的文档,希望能够以此来提高各位粉丝的通过率

ee90d9963df444db88b33d6e798a5b94.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
80 2
基于Redis的高可用分布式锁——RedLock
|
26天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
9天前
|
NoSQL 安全 关系型数据库
20)用 Redis 实现分布式锁
20)用 Redis 实现分布式锁
20 0
|
2月前
|
NoSQL Go Redis
用 Go + Redis 实现分布式锁
用 Go + Redis 实现分布式锁
|
15天前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
15天前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
15天前
|
存储 负载均衡 Dubbo
分布式-Zookeeper(一)
分布式-Zookeeper(一)
|
3月前
|
监控 NoSQL Java
分布式锁实现原理问题之ZooKeeper的观察器(Watcher)特点问题如何解决
分布式锁实现原理问题之ZooKeeper的观察器(Watcher)特点问题如何解决
|
15天前
分布式-Zookeeper-数据订阅
分布式-Zookeeper-数据订阅
|
15天前
|
监控
分布式-Zookeeper-Zab协议
分布式-Zookeeper-Zab协议