基于Redis的高可用分布式锁——RedLock

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。

RedLock简介

  1. Redis作者提出来的高可用分布式锁
  2. 由多个完全独立的Redis节点组成,注意是完全独立,而不是主从关系或者集群关系,并且一般是要求分开机器部署的
  3. 利用分布式高可以系统中大多数存活即可用的原则来保证锁的高可用
  4. 针对每个单独的节点,获取锁和释放锁的操作,完全采用我们上面描述的单机版的方式

RedLock工作流程

获取锁

  1. 获取当前时间T1,作为后续的计时依据;
  2. 按顺序地,依次向5个独立的节点来尝试获取锁
  • (SET resource_name my_random_value NX PX 30000)
  1. 计算获取锁总共花了多少时间,判断获取锁成功与否
  • 时间:T2-T1

  • 多数节点的锁(N/2+1)

  1. 当获取锁成功后的有效时间,要从初始的时间减去第三步算出来的消耗时间

  2. 如果没能获取锁成功,尽快释放掉锁。

这里需要注意两点:

  1. 为什么要顺序地向节点发起命令,那么我们反过来想,假如不顺序地发起命令会产生什么问题?
    假如有3个客户端同时来抢锁,客户端A先获取到1号和2号节点,客户端B先获取到3号4号节点,客户端C先获取到5号节点,那么这时候就满足不了多数原则,5个节点的情况下,最少需要3个节点都获取到锁,才可以满足。

  2. 客户端在向每个节点尝试获取锁的时候,有一个超时时间限制,而且这个时间远小于锁的有效期,比如说几毫秒到几十毫秒之间,这样的机制是为了防止在向某一个节点获取锁的时候,等待的时间过长,从而导致获取锁的整体时间过长。比如说在获取锁的时候,有的节点会出现问题导致连接不上,那么这个时候就应该尽快地转移到下一个节点继续尝试,因为最终的结果我们只需要满足多数可用原则即可

释放锁

向所有节点发起释放锁的操作,不管这些节点有没有成功设置过.

正常情况下RedLock的运行状态

client1和client2,对Redis节点A-E进行抢锁操作,如图,client1先抢到节点ABC,超过半数,因此持有分布式锁,在持有锁期间,client2抢锁都是失败的,当时序=6时,client1才处理完业务流程释放分布式锁,这时候client2才有可能抢锁成功。

那么RedLock的主要流程就是这样,获取锁和释放锁,那么这个号称是真正的分布式锁,相比前面单机版的锁,很明显的一个点就是它不再是单点的,所以在高可用性上面,它是比单机版的锁有提升的。

但是,RedLock 是否就是一个很完美的解决方案呢?在一些特殊场景下会不会存在什么不足的地方?

此外,除了redis以外 ,其实我们可以用ZooKeeper来实现分布式锁

实际上Redis实现分布式锁的方式虽然性能比较高,但是在一些特殊场景下,它还是不够健壮,相比之下,ZooKeeper它的设计定位就是用来做分布式协调的工作,更加注重一致性,非常适合用来做分布式锁,总的来说使用ZooKeeper去实现分布式锁相比Redis的话会更加健壮一些。

相关实践学习
基于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 Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
19天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
53 16
|
2月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
64 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
2月前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
51 1
|
2月前
|
NoSQL 算法 关系型数据库
Redis分布式锁
【10月更文挑战第1天】分布式锁用于在多进程环境中保护共享资源,防止并发冲突。通常借助外部系统如Redis或Zookeeper实现。通过`SETNX`命令加锁,并设置过期时间防止死锁。为避免误删他人锁,加锁时附带唯一标识,解锁前验证。面对锁提前过期的问题,可使用守护线程自动续期。在Redis集群中,需考虑主从同步延迟导致的锁丢失问题,Redlock算法可提高锁的可靠性。
80 4
|
2月前
|
存储 NoSQL 大数据
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
35 3
|
2月前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
49 0
|
2月前
|
缓存 NoSQL 算法
面试题:Redis如何实现分布式锁!
面试题:Redis如何实现分布式锁!
|
4月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
2月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
66 4