blpop阻塞问题

来源:4-4 发布订阅

Panda_io

2020-04-25

老师redis是单线程,当我使用blpop key 0 时线程出现阻塞,既然线程阻塞了,其他操作就应该不能执行了我的理解是这样,但是为何我可以重开一个客户端,把值push进去呢

图片描述

图片描述

我就是不明白,既然是单线程,线程阻塞了,那么肯定不能处理其他任务了呀,请老师指点一下

写回答

1回答

carlosfu

2020-06-24

执行blpop等阻塞命令时,主要调用t_list中的void blpopCommand(redisClient *c)函数,该函数主要是调用blockingPopGenericCommand(c,REDIS_HEAD)来进行最终命令的执行

这样组可以使得brpop命令也调用该函数,只需要改变pop的方向。



如果发生了超时错误,则直接返回

否则就使用lookupKeyWrite判断键是否存在,如果键存在但是不是list类型,那么就返回一个类型错误给客户端;否则就对list进行操作,当list的长度不为0时,就从链表中弹出一个元素并返回给客户端,如果此时list长度为0,那么就调用删除程序,在aof文件中使用l[r]pop命令记录,而不是使用阻塞的命令进行计算。换句话说,如果bl[r]pop操作list时,如果list不为空,那么和l[r]pop的操作是一样的。


如果命令在事务中执行,则会返回一个空回复


如果所有的请求的键不存在,则对客户端进行阻塞。服务器不再对这个客户端发送任何数据,对这个客户端的状态设为“被阻塞“,直到解除阻塞为止。并且客户端会被加入到一个以阻塞键为 key ,以被阻塞客户端为 value 的字典 db->blocking_keys 中。

当有 PUSH 命令作用于一个造成客户端阻塞的键时, 程序将这个键标记为“就绪”,并且在执行完这个命令、事务、或脚本之后,程序会按“先阻塞先服务”的顺序,将列表的元素返回给那些被阻塞的客户端,被解除阻塞的客户端数量取决于 PUSH 命令推入的元素数量。


1
1
Panda_io
哇 感谢老师这么细心的解释,老师太敬业了,爱了爱了
2020-06-24
共1条回复

一站式学习Redis 从入门到高可用分布式实践

Redis课程升级!系统梳理Redis知识体系,掌握redis必备!

2277 学习 · 261 问题

查看课程