Redis 源码剖析与实战
蒋德钧
中科院计算所副研究员
17747 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
Redis 源码剖析与实战
15
15
1.0x
00:00/00:00
登录|注册

14 | 从代码实现看分布式锁的原子性保证

你好,我是蒋德钧。
分布式锁是 Redis 在实际业务场景中的一个重要应用。当有多个客户端并发访问某个共享资源时,比如要修改数据库中的某条记录,为了避免记录修改冲突,我们可以让所有客户端从 Redis 上获取分布式锁,只有拿到锁的客户端才能操作共享资源。
那么,对于分布式锁来说,它实现的关键就是要保证加锁和解锁两个操作是原子操作,这样才能保证多客户端访问时锁的正确性。而通过前面课程的学习,你知道 Redis 能通过事件驱动框架同时捕获多个客户端的可读事件,也就是命令请求。此外,在 Redis 6.0 版本中,多个 IO 线程会被用于并发地读取或写回数据。
而既然如此,你就可以来思考一个问题:分布式锁的原子性还能得到保证吗?
今天这节课呢,我就带你来了解下一条命令在 Redis server 中的执行过程,然后结合分布式锁的要求,来带你看下命令执行的原子性是如何保证的。同时,我们再来看看在有 IO 多路复用和多 IO 线程的情况下,分布式锁的原子性是否会受到影响。
这样一来,你就既可以掌握客户端的一条命令是如何完成执行的,其原子性是如何得到保证的,而且还可以把之前学习到的知识点串接应用起来。要知道,了解客户端命令的执行过程,对于日常排查 Redis 问题也是非常有帮助的,你可以在命令执行的过程中加入检测点,以便分析和排查运行问题。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Redis中的分布式锁实现原理及命令执行过程 本文深入介绍了Redis中分布式锁的实现原理和命令执行过程。首先,作者解释了分布式锁的重要性,并介绍了通过Redis的SET命令实现加锁和使用Lua脚本实现解锁的方法。接着,讨论了在具有IO多路复用和多IO线程的情况下,分布式锁的原子性是否会受到影响。文章详细介绍了命令在Redis中的处理过程,包括命令读取、解析、执行和结果返回四个阶段的基本流程和内部调用关系。通过对processInputBuffer和processCommand函数的分析,读者可以了解命令解析和执行的基本流程。最后,通过以SET命令为例,展示了命令执行的具体过程,包括参数判断、键值对插入、过期时间设置和结果返回。本文通过深入分析Redis中分布式锁的实现原理和命令执行过程,帮助读者更好地理解分布式锁的工作机制和Redis命令的执行过程。 文章重点介绍了Redis中分布式锁的实现原理和命令执行过程,包括分布式锁的加锁和解锁方法,以及命令在Redis中的处理过程。此外,还讨论了在具有IO多路复用和多IO线程的情况下,分布式锁的原子性是否会受到影响。通过对命令执行过程中的IO多路复用和多IO线程的影响进行分析,文章强调了即使使用了多IO线程,命令执行的原子性仍然可以得到保证。整体而言,本文为读者提供了深入了解Redis分布式锁实现原理和命令执行过程的重要参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 源码剖析与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • Kaito
    1、无论是 IO 多路复用,还是 Redis 6.0 的多 IO 线程,Redis 执行具体命令的主逻辑依旧是「单线程」的 2、执行命令是单线程,本质上就保证了每个命令必定是「串行」执行的,前面请求处理完成,后面请求才能开始处理 3、所以 Redis 在实现分布式锁时,内部不需要考虑加锁问题,直接在主线程中判断 key 是否存在即可,实现起来非常简单 课后题:如果将命令处理过程中的命令执行也交给多 IO 线程执行,除了对原子性会有影响,还会有什么好处和坏处? 好处: - 每个请求分配给不同的线程处理,一个请求处理慢,并不影响其它请求 - 请求操作的 key 越分散,性能会变高(并行处理比串行处理性能高) - 可充分利用多核 CPU 资源 坏处: - 操作同一个 key 需加锁,加锁会影响性能,如果是热点 key,性能下降明显 - 多线程上下文切换存在性能损耗 - 多线程开发和调试不友好
    2021-08-26
    2
    17
  • 芋圆Magic
    老师,有个疑问,多线程版本是在命令读取,解析和返回结果是并行的,执行是在主线程处理,是串行的。那样从整个数据流来看,是不是就保证不了命令的执行顺序了?比如命令A比命令B先到Redis服务,但是有可能B会比A先被执行了。
    2021-09-04
    3
    5
  • 云海
    1,客户端A 先发起请求1,后客户端B发起请求2,服务端【无法保证】先接收到 请求1后接收到请求2,因为网络传输时间不同。 2,客户端A 先发起请求1,后客户端A再次发起请求2,服务端 【可以保证】 先接收到请求1后接收到请求2,这个由TCP来保证。 3,服务端先接收到请求1,后接收到请求2,在多io环境下,redis【可以保证】先执行请求1后执行请求2。请求会先放到列表里,多IO线程从列表依次获取请求,进行命令读取及解析,io线程都解析完第一个请求后,主线程是按序执行。
    2021-10-11
    2
  • 小五
    为什么 IO 线程只是完成解析第一个读到的命令,而不是直接将Client输入缓冲解析完?
    2021-09-10
    2
    2
  • 自律给我自由
    多线程读取命令是怎么保证顺序的?业务上是A客户端先读,B客户端再写,同时到了Redis服务端后,执行B客户端的线程比执行A客户端的线程先完成了,那给到主线程的命令执行阶段顺序不是就错了?
    2021-09-01
    2
    2
  • redisCommand 结构体中 每一个代表什么什么意思的? struct redisCommand { char *name; redisCommandProc *proc; int arity; char *sflags; /* Flags as string representation, one char per flag. */ int flags; /* The actual flags, obtained from the 'sflags' field. */ /* Use a function to determine keys arguments in a command line. * Used for Redis Cluster redirect. */ redisGetKeysProc *getkeys_proc; /* What keys should be loaded in background when calling this command? */ int firstkey; /* The first argument that's a key (0 = no keys) */ int lastkey; /* The last argument that's a key */ int keystep; /* The step between first and last key */ long long microseconds, calls; };
    2021-08-29
    1
  • Milittle
    这节课在学习之前,有80%内容是之前通过学习前面课程结合源码知晓的,老师再一串更加完整了。 有一个问题是:单机redis,在开启多线程读写的时候,qps最高可以打到多少?多谢老师
    2021-08-26
    1
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部