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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
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
相关文章
|
14天前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
22天前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
40 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
10天前
|
消息中间件 架构师 Java
阿里面试:秒杀的分布式事务, 是如何设计的?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试阿里、滴滴、极兔等一线互联网企业时,遇到了许多关于分布式事务的重要面试题。为了帮助大家更好地应对这些面试题,尼恩进行了系统化的梳理,详细介绍了Seata和RocketMQ事务消息的结合,以及如何实现强弱结合型事务。文章还提供了分布式事务的标准面试答案,并推荐了《尼恩Java面试宝典PDF》等资源,帮助大家在面试中脱颖而出。
|
14天前
|
NoSQL Java API
美团面试:Redis锁如何续期?Redis锁超时,任务没完怎么办?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试一线互联网企业时遇到了关于Redis分布式锁过期及自动续期的问题。尼恩对此进行了系统化的梳理,介绍了两种核心解决方案:一是通过增加版本号实现乐观锁,二是利用watch dog自动续期机制。后者通过后台线程定期检查锁的状态并在必要时延长锁的过期时间,确保锁不会因超时而意外释放。尼恩还分享了详细的代码实现和原理分析,帮助读者深入理解并掌握这些技术点,以便在面试中自信应对相关问题。更多技术细节和面试准备资料可在尼恩的技术文章和《尼恩Java面试宝典》中获取。
美团面试:Redis锁如何续期?Redis锁超时,任务没完怎么办?
|
15天前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
35 1
|
19天前
|
NoSQL 算法 关系型数据库
Redis分布式锁
【10月更文挑战第1天】分布式锁用于在多进程环境中保护共享资源,防止并发冲突。通常借助外部系统如Redis或Zookeeper实现。通过`SETNX`命令加锁,并设置过期时间防止死锁。为避免误删他人锁,加锁时附带唯一标识,解锁前验证。面对锁提前过期的问题,可使用守护线程自动续期。在Redis集群中,需考虑主从同步延迟导致的锁丢失问题,Redlock算法可提高锁的可靠性。
49 4
|
20天前
|
NoSQL 算法 Redis
Redis面试篇
Redis面试篇
31 5
|
21天前
|
缓存 NoSQL Java
Java中redis面试题
Java中redis面试题
28 1
|
1天前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
19天前
|
缓存 NoSQL 算法
面试题:Redis如何实现分布式锁!
面试题:Redis如何实现分布式锁!

热门文章

最新文章