Redis CLIENT UNBLOCK 命令可以通过其他连接解除客户端的阻塞状态,如客户端正在执行具有阻塞功能的命令,比如 BRPOP、XREAD 或者 WAIT 等阻塞命令时。
命令格式
CLIENT UNBLOCK client-id [TIMEOUT|ERROR]
可用版本:>=5.0.0
时间复杂度:O(N),N 为 Redis 服务的客户端连接数。
默认情况下,命令设置的超时时间(timeout)到达时,客户端的阻塞状态会解除。除此之外,命令也提供了可以指定解除阻塞的行为,可以是 TIMEOUT(默认)或 ERROR。如指定为 ERROR,客户端会强制被解除阻塞,客户端会返回如下信息:
-UNBLOCKED client unblocked via CLIENT UNBLOCK
提示:通常情况下,不保证返回的 error 文本一样,但是返回的 error 文本比包含 -UNBLOCKED。
使用场景
这个命令,在仅能使用较少连接但要监控大量 keys 的时候特别有用。
例如使用命令 XREAD 和很少连接监控多个消息流,在某个时间点,信息流消费进程需要新增一个消息流 key 的监控,为了避免使用更多连接,最好的方法是从连接池中停掉一个阻塞的连接,增加新的要监控的 key,再重启该阻塞命令即可。
我们使用如下操作流程来实现这种操作:
- 管理进程使用额外的连接 control connection,在必要时,执行 CLIENT UNBLOCK,同时,在某一连接执行阻塞命令之前,进程执行 CLIENT ID 以获取该连接的 ID 值。
- 当需要监控一个新增的 key 或者取消一个 key 的监控时,通过在 control connection 中执行 CLIENT UNBLOCK 加上上一步获取的 ID 值来解除相关连接的阻塞。监控 key 调整后,再次执行阻塞命令即可。
示例
上述例子,以 Redis streams 为例,介绍了操作流程,该操作流程也可以应用到其他数据结构类型:
Connection A (blocking connection):
> CLIENT ID
2934
> BRPOP key1 key2 key3 0
(client is blocked)
... Now we want to add a new key ...
Connection B (control connection):
> CLIENT UNBLOCK 2934
1
Connection A (blocking connection):
... BRPOP reply with timeout ...
NULL
> BRPOP key1 key2 key3 key4 0
(client is blocked again)