广告
返回顶部
首页 > 资讯 > 数据库 >Redis中Redlock的示例分析
  • 665
分享到

Redis中Redlock的示例分析

2024-04-02 19:04:59 665人浏览 薄情痞子
摘要

这篇文章主要介绍了Redis中Redlock的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。为什么要用锁我待过的一家k12教育公司,

这篇文章主要介绍了Redis中Redlock的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

为什么要用锁

我待过的一家k12教育公司,我们当时有个业务场景是这样的。业务这边要给学生排课,偶尔会反馈学生的课时明明充足的但是却提示课时不足,等再刷新一遍页面却发现学生的课时已经不够了。更可怕的是,偶尔会有学生的课时被扣成负数(公司被白嫖课时)。

再比如下面这个例子

Redis中Redlock的示例分析

上面的这俩个问题都是并发给我们的业务带来的问题。解决这个问题的核心就是,同一时间只能允许有一个请求来对这些敏感(重要)的数据进行读写操作。所以这个时候就要使用到分布式来限制程序的并发执行。

setnx有哪些问题

我们先来看看用Redis如何实现分布式锁,想必大家都很熟悉。比如针对我文章开头讲的学生排课的问题我们就可以这样加锁

Redis中Redlock的示例分析

这就是我们常规使用setnx来实现锁的方式。

现在我们假设有这样一个场景。A请求拿到锁到了第2步给学生排课的时候程序挂了,没有释放锁。那么这个锁就成了死锁,下一个操作同一个学生的请求永远就拿不到锁,那么这个学生就没法被排课了。这个时候都需要手动去把锁释放掉。

为了解决死锁的问题,我们给锁加一个过期时间。

Redis中Redlock的示例分析

加上过期时间之后,如果A请求没有主动释放锁,在锁过期之后也会主动释放,这样B请求一样可以获取锁处理业务逻辑。但是如果在加过期时间的时候也就是在第1步和第2步之间程序崩溃。那还是会出现死锁的问题。这个问题的根源就在于setnx和expire这两条指令不是原子指令。所以如果setnx和expire能够要么全部执行要么一个都不执行那该多好。

为此在Redis2.8之前社区涌现了一大批扩展包来解决该问题。官方为了治理该乱象,在2.8版本中加入了set指令的扩展参数使得setnx和expire指令可以一起执行,所以现在我们使用分布式锁应该是这样了

Redis中Redlock的示例分析

这样看起来已经很完美了,已经达成了我们的期望“setnx和expire能够要么全部执行要么一个都不执行那该多好”。我们再假设现在有如下场景:

A请求现在获取到了锁,锁的超时时间设置的是5秒。到了第2步执行业务逻辑,结果因为某些原因5秒之后业务逻辑还没有执行完,此时锁由于超时自动释放了。这个时候B请求也来了,拿到锁之后开始执行业务逻辑。A请求这个时候业务逻辑执行完了,开始执行第三步,释放了锁。而这个时候锁是B请求拿到的,结果被A请求释放了。那么C请求就可以拿到锁了。这个时候B请求和C请求就会导致并发问题了。所以可以从这个例子看出来,在分布式锁中过期时间的设置非常重要,如果设置的时间小于这个接口的响应时间那么仍然会产生并发问题。所以我们可以参考接口响应时长的监控来设置锁的过期时间。

Redlock

我们上述的方案都是基于单点的Redis的实现方式。单点的Redis实现分布式锁基本上可以满足95%的业务场景。剩下的5%就是对数据一致性要求极其严苛并且对于锁丢失的0容忍的业务场景。这个时候就得考虑Redlock了。至于单点的Redis即使通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,如果数据主从数据同步不及时那么势必会有数据丢失,那么就会出现锁丢失的情况。

假设存在多个Redis实例,这些节点是完全独立的,不需要使用复制或者任何协调数据的系统,我们假设有5个Redis master节点,客户端为了取到锁,步骤将会变成这样:

  • 以毫秒为单位获取当前的服务器时间

  • 尝试使用相同的key和随机值来获取锁,客户端对每一个机器获取锁时都应该有一个超时时间,比如锁的过期时间为10s,那么获取单个节点锁的超时时间就应该为5到50毫秒左右,他这样做的目的是为了保证客户端与故障的机器连接不耗费多余的时间!超时间时间内未获取数据就放弃该节点,从而去下一个Redis节点获取。

  • 获取完成后,获取当前时间减去步骤一获取的时间,当且仅当客户端从半数以上(这里是3个节点)的Redis节点获取到锁且获取锁的时间小于锁额超时时间,则证明该锁生效!

  • 如果取到了锁,key的真正有效时间等于有效时间减去获取锁所使用的时间(步骤3计算的结果)。

  • 如果获取锁的机器不满足半数以上,或者锁的超时时间计算完毕后为负数等异常操作,则系统会尝试解锁所有实例,即便某些Redis实例根本就没有加锁成功,防止某些节点获取到锁但是客户端没有得到响应而导致接下来的一段时间不能被重新获取锁

所以我们看出,redlock其实是比单点Redis看起来更加可靠的锁。

如果你跟我一样是node.js程序员那么正好有第三方库redlock直接使用。

我们真的需要redlock吗

关于redlock其实也有另外一种声音,Martin Kleppmann(剑桥大学的研究员,从事数据库分布式系统和信息安全交叉领域的TRVE DATA项目)写过一篇blog发表了关于对redlock的一些看法,感兴趣的可以看看。Redis作者Salvatore也对这篇文章的疑问做出了一些回应,还挺有意思的。作者的blog主要的观点如下:

分布式锁的用途无非两种:

  • 效率:使用锁可以避免不必要地做同样的工作两次(例如一些昂贵的计算)。如果锁定失败并且两个节点最终完成相同的工作,结果是成本略有增加(您最终向 AWS 支付的费用比其他情况多 5 美分)或带来轻微的不便(例如,用户最终两次收到相同的电子邮件通知)。

  • 正确性:使用锁可以防止并发进程相互干扰并破坏系统状态。如果锁定失败并且两个节点同时处理同一条数据,则结果是文件损坏、数据丢失、永久性不一致、给患者服用的药物剂量错误或其他一些非常严重的问题。

如果是为了效率,则根本没有必要承担 Redlock 的成本和复杂性,锁丢失导致多发几次邮件和运行 5 个 Redis 服务器的成本相比,最好只使用单个 Redis 实例。如果你使用的是单个 Redis 实例,Redis 节点突然断电或者崩溃,或者出现其他问题,这个时候当然会丢失锁。但是如果你只是将锁用作效率优化,而且这种崩溃不会经常发生,那没什么大不了的。这种“没什么大不了”的场景是 也恰好是Redis优秀的地方。至少如果依赖单个 Redis 实例,那么查看系统的每个人都能够更方便的定位问题。

如果是为了正确性,那么严格来讲,redlock根本不具有强一致的严格性。举了一些例子

  • 时序和系统时钟做出了危险的假设,对每台服务器的时钟强依赖。因为有系统有GC的存在,做GC的时整个服务器是夯住的,时间也就停滞了,所以我们不能够对时钟有强依赖。

  • 没有令牌。客户端每次获取锁的时候服务端没有下发令牌,服务端应该校验每次操作的时候客户端的令牌要与服务端当前的令牌一致才难操作锁。

感谢你能够认真阅读完这篇文章,希望小编分享的“Redis中Redlock的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网数据库频道,更多相关知识等着你来学习!

您可能感兴趣的文档:

--结束END--

本文标题: Redis中Redlock的示例分析

本文链接: https://www.lsjlt.com/news/71927.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis中Redlock的示例分析
    这篇文章主要介绍了Redis中Redlock的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。为什么要用锁我待过的一家k12教育公司,...
    99+
    2022-10-19
  • Redis中分布式锁Redlock的示例分析
    这篇文章主要介绍了Redis中分布式锁Redlock的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Redlock实现库Java Redisson Star 9458...
    99+
    2023-06-16
  • Redis中Cluster的示例分析
    小编给大家分享一下Redis中Cluster的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.1 Redis-Clus...
    99+
    2022-10-18
  • Redis分区的示例分析
    这篇文章主要介绍了Redis分区的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Redis是单线程的,如何提高多核CPU的利用率?可...
    99+
    2022-10-19
  • Redis中链表的示例分析
    这篇文章主要介绍Redis中链表的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1 链表和链表节点的结构1 节点结构节点的结构大概长下边这个样子:那么,把这些节点就连起来就成了这个样子:2 链表结构链表自然除...
    99+
    2023-06-22
  • Redis中RDB和AOF的示例分析
    这篇文章将为大家详细讲解有关Redis中RDB和AOF的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redis 有两种持久化方案,RDB (Redis Data...
    99+
    2022-10-18
  • Redis中cluster集群的示例分析
    这篇文章主要为大家展示了“Redis中cluster集群的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Redis中cluster集群的示例分析”这篇文...
    99+
    2022-10-18
  • Redis瘦身的示例分析
    这篇文章主要介绍Redis瘦身的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Redis内存回收Redis 服务器的最大占用内存量由配置项 maxmemory 决定,我们可以通过 config set max...
    99+
    2023-06-15
  • Redis集群的示例分析
    这篇文章主要介绍Redis集群的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Redis集群详解Redis有三种集群模式,分别是:* 主从模式 * Se...
    99+
    2022-10-18
  • Redis协议的示例分析
    这篇文章给大家分享的是有关Redis协议的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。前言我们用过很多redis的客户端,有没有相过自己撸一个redis客户端? 其实很...
    99+
    2022-10-18
  • redis事务的示例分析
    这篇文章将为大家详细讲解有关redis事务的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一: 事务实战具体到事务是什么,要保证什么。。。这个我想没必要...
    99+
    2022-10-18
  • Redis分布式锁Redlock的实现
    目录普通实现Redlock实现Redlock源码用法唯一ID获取锁释放锁普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value p...
    99+
    2022-11-12
  • Redis分布式锁的示例分析
    小编给大家分享一下Redis分布式锁的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!第一版本:@Override pu...
    99+
    2022-10-18
  • Redis中主从复制的示例分析
    这篇文章给大家分享的是有关Redis中主从复制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。面临问题 机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数...
    99+
    2023-06-15
  • Redis中哨兵模式的示例分析
    小编给大家分享一下Redis中哨兵模式的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!主从切换技术的方法是:当主服务器宕...
    99+
    2022-10-18
  • redis中事务操作的示例分析
    这篇文章主要介绍了redis中事务操作的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。redis与mysql的事务Redis支持简单...
    99+
    2022-10-18
  • Redis中管道机制的示例分析
    这篇文章将为大家详细讲解有关Redis中管道机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Pipeline简介Redis客户端执行一条命令:发送命令命令排队...
    99+
    2022-10-18
  • Redis中连接错误的示例分析
    这篇文章主要介绍Redis中连接错误的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言最近由于流量增大,redis 出现了一连串错误,比如:LOADING Redis is...
    99+
    2022-10-18
  • redis中redisson限流器的示例分析
    这篇文章主要介绍了redis中redisson限流器的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。redis redisson 限流器实例作用:限制一段时间内对数据...
    99+
    2023-06-20
  • Redis中过期策略的示例分析
    小编给大家分享一下Redis中过期策略的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!概述设置过期时间expire key time(以秒为单位) 这是最...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作