Redis阻塞操作实现原理

更新时间:2023-08-11 04:35:59 阅读: 评论:0

down by the salley gardens
Redis阻塞操作实现原理
最近⼀位朋友问到:既然Redis是单线程的⼯作模式,那像BLPOP这样的阻塞操作⼜是然后实现的呢?
接下来分别从服务端和客户端来阐述这⼀逻辑的实现原理。
Redis Server:
redis实现了⼀套事件触发模型,主要处理两种事件:I/O事件(⽂件事件)和定时事件。⽽处理它们的就靠⼀个EventLoop线程。同时redis还提供了丰富的数据结构,今天我们要分析的主要是List数据结构中的阻塞命令。
职教英语
内容英文先来看看BLPOP的源码(做了精简,只看主要的部分,详细的可以看⽂尾提供的参考链接):
mykonos>aimini
t_list.c
t_list.c_1.png
cuit
t_list.c_2.png
上⾯代码表明:如果客户端发来⼀个blpop key命令,redis先找到对应的key的list,如果list不为空则pop⼀个数据返回给客户端;如果对应的list不存在或者⾥⾯没有数据,就将该key添加到⼀个blockling_keys的字典中,value就是想订阅该key的client链表。此时对应的client的为block状态,且i/o channel⾥⾯没有写⼊数据。
既然是list数据结构,当然有push数据的操作:
同样是t_list.c
小学数学课堂教学的有效性t_list.c_3.png
t_list.c_4.png少儿英语教学
上⾯代码表明:如果客户端发来⼀个repush key value命令,先从blocking_keys中查找是否存在对应的key,如果存在就往ready_keys这个链表中添加该key;同时将value插⼊到对应的list中,并响应客户端。
从上⾯的分析来看,主要是blocking_keys和ready_keys的作⽤,那何时才会处理它们呢? 我们知道redis全靠EventLoop来处理所以的I/O事件,我们来看看所以命令的处理⼊⼝:
redis.c
redis.c_1.png
t_list.c_5.png
t_list.c_6.png
上⾯代码表明:每次处理完客户端命令后都会遍历ready_keys,并通过blocking_keys找到对应的client,依次将对应list的数据pop出来并响应对应的client;同时检查是否需要再次block。
这样⼀来整个流程就清晰了。redis就是通过blocking_keys和ready_keys两个数据结构来实现的阻塞操作。但整个阻塞并没有阻塞EventLoop 本⾝,从⽽实现命令的快速响应。算是⼀个典型的空间换时间的设计思路。
接下来再看看客户端如何实现⼀个阻塞的I/O请求。
Client:
这⾥我们分两种I/O模型来阐述:阻塞I/O(BIO)和⾮阻塞I/O(NIO)。
BIO,以Jedis为例。
BinaryJedis.java
BinaryJedis.java.png
可以看出⼀个blpop请求会向redis发起两次I/O请求,⼀次向redis发送BLPOP key命令,⼀次从对应的链接管道(channel)中读取数据。由于BIO的特性当channel中没有数据时会⼀直阻塞,直到有新数据为⽌。这样就实现了客户端的阻塞效果。
发音字典
注意:这⾥的链接是被独享的,不然会有数据⼲扰。
NIO的实现就稍微复杂⼀些,这⾥分两种情况(以netty为例):
demonstration不带RquestID的实现⽅式
伪代码如下:

本文发布于:2023-08-11 04:35:59,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1129156.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:阻塞   客户端   对应
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图