BLOCK 命令的业务逻辑:
Redis 5.0.x 支持 三种类型的 block 操作
1. list Blocked pop
2. zset Blocked pop
3. stream Blocked xread(5.0 新增)
list 与 zset blocked pop 操作,逻辑基本一致。
1. 客户端发送 block pop 命令
2. 需要 pop 的 target 中 为空(在Redis server中:该 target 并不存在,如果存在,并返回错误,那么将返回类型错误)
3. 客户端 blocked, Redis 内部将 target & client 的指针同时添加入对应 db 的 blocking_keys dict 中。
此时 block command 暂时告一段落,以上设置都是都各命令中根据命令自身的属性,各自独立处理的
接下来每当用户操作一个 key 值时,
1. 如果是 new add 操作
2. add 的数据类型是 LIST
3. 该 key 值在对应 db (0 ~ 15号相互独立) 的 blocking_keys dict 中存在
那么, 该 key 值将会被 插入 server ready_keys 链表中
4. 每次 processCommand 的末尾,都会遍历这个 链表,进行相应的处理。
Redis 此处对于各个命令的处理,并没有抽象出特定框架,都是半 hard code的方式。
TIMEOU 检查:
在serverCron 的 clientCron中周期的进行 timeout的检查,并且进行timeout结果返回。
特别需要说明几点:
1. BLPOP/BRPOP target_lists timeout, target_lists 可以同时“监听”多个list,只要有一个非空,就会返回。
2. Redis中的16个db是相互独立的空间,也就是说 BLPOP target_list 0 默认选择的是0号db,当1号db中有push操作,前面的BLPOP操作并不会返回。
3. Redis 中并没有明确给出有 session 的概念,但是有一些操作,是有实际 session概念存在的,是利用TCP的保持连接实现的,在命令完成之前,客户端是不允许断开连接的,否则,将拿不到最终结果。尤其是当存在 multi 事务时,后续会单独针对该部分进行详细阐述