bigywater.tech
Redis · 45

XAUTOCLAIM

上一篇里,认领崩溃消费者遗留的消息要靠 XCLAIM,而 XCLAIM 需要你事先知道 ID。XAUTOCLAIM 把「找出超时的消息」和「认领」合成一步,用游标翻页。这篇验证它的返回值、翻页规则、JUSTID,以及消息在流里已被删除时的处理。

4 次
10 条 pending、COUNT 3:翻页扫完所需的调用次数
0-0
返回游标回到 0-0 = 扫描完毕
JUSTID
只转移所有权,不返回消息体,投递次数不 +1

用游标翻页认领

实测 · 本机执行输出
游标   0-0 → 下一个游标   4-0  认领 ['1-0', '2-0', '3-0']  已删除 []
游标   4-0 → 下一个游标   7-0  认领 ['4-0', '5-0', '6-0']  已删除 []
游标   7-0 → 下一个游标  10-0  认领 ['7-0', '8-0', '9-0']  已删除 []
游标  10-0 → 下一个游标   0-0  认领 ['10-0']  已删除 []

A 读了 10 条不 ack。B 用 XAUTOCLAIM s g B 500 0-0 COUNT 3 从游标 0-0 开始认领空闲 ≥ 500 ms 的消息,每次最多 3 条。返回的三项依次是:下一个游标、被认领的消息(带内容)、已被删除的 ID 列表。把返回的游标传给下一次调用,直到游标回到 0-0——4 次调用扫完 10 条。

认领之后 idle 归零

实测 · 本机执行输出
> XPENDING s g - + 3
1) 1) "1-0"
   2) "B"
   3) (integer) 1
   4) (integer) 2
2) 1) "2-0"
   2) "B"
   3) (integer) 1
   4) (integer) 2
3) 1) "3-0"
   2) "B"
   3) (integer) 1
   4) (integer) 2
> XAUTOCLAIM s g C 500 0-0 COUNT 3
1) "0-0"
2) (empty array)
3) (empty array)

认领让消息的 idle 重置(1 ms)、投递次数从 1 变成 2。所以马上再来一轮返回空——所有消息都还没空闲到 500 ms。这正是多个恢复进程并行跑 XAUTOCLAIM 时不会重复认领的原因。

JUSTID

实测 · 本机执行输出
> XAUTOCLAIM s g C 500 0-0 COUNT 3 JUSTID
1) "4-0"
2) 1) "1-0"
   2) "2-0"
   3) "3-0"
3) (empty array)
> XPENDING s g - + 3
1) 1) "1-0"
   2) "C"
   3) (integer) 0
   4) (integer) 2
2) 1) "2-0"
   2) "C"
   3) (integer) 0
   4) (integer) 2
3) 1) "3-0"
   2) "C"
   3) (integer) 0
   4) (integer) 2

加上 JUSTID 之后,返回值里只有 ID,没有消息内容,并且不增加投递次数(XPENDING 里 1-0 到 3-0 的次数仍是 2,和上一步相同),但所有权确实转给了 C。

消息已被删除时

实测 · 本机执行输出
> XDEL s 4-0 5-0
(integer) 2
> XAUTOCLAIM s g D 500 0-0 COUNT 10
1) "0-0"
2) 1) 1) "1-0"
      2) 1) "job"
         2) "j1"
   2) 1) "2-0"
      2) 1) "job"
         2) "j2"
   3) 1) "3-0"
      2) 1) "job"
         2) "j3"
   4) 1) "6-0"
      2) 1) "job"
         2) "j6"
   5) 1) "7-0"
      2) 1) "job"
         2) "j7"
   6) 1) "8-0"
      2) 1) "job"
         2) "j8"
   7) 1) "9-0"
      2) 1) "job"
         2) "j9"
   8) 1) "10-0"
      2) 1) "job"
         2) "j10"
3) 1) "4-0"
   2) "5-0"
> XPENDING s g
1) (integer) 8
2) "1-0"
3) "10-0"
4) 1) 1) "D"
      2) "8"

把 4-0、5-0 XDEL 之后,D 执行 XAUTOCLAIM:这两条从 PEL 中被移除(XPENDING 总数从 10 降到 8),并列在返回值的第三个元素里,其余 8 条正常认领。

翻页的调用次数

实测 · 本机执行输出
10 条 pending,COUNT 3:4 次 XAUTOCLAIM 调用扫完(最后一次返回游标 0-0)

分步演示:游标翻页与所有权转移

XAUTOCLAIM
本次认领的消息

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:XAUTOCLAIM 在旧版本上的行为(只测了本机这一个版本)、PEL 很大时的耗时、COUNT 的上限
    京ICP备2026067502号-1京公网安备11010502063487号