diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index c187b29..5941edc 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -105,6 +105,9 @@ - [XREADGROUP](#xreadgroup) - [Recovering from permanent failures](#recovering-from-permanent-failures) - [XPENDING](#xpending) + - [checking the message content](#checking-the-message-content) + - [XCLAIM](#xclaim) + - [JUSTID option](#justid-option) # redis @@ -1759,7 +1762,9 @@ XREADGROUP命令基于指定id的不同,行为拥有如下区别: XREADGROUP有如下方面需要关注: - consumer并不需要显式创建,`consumers are auto-created the first time they are mentioned` - 在使用XREADGROUP时,可以同时读取多个keys。但是,想要令该操作可行,`必须create a consumer group with the same name in every stream`。该方式通常不会被使用,但是在技术上是可行的 -- `XREADGROUP`为一个`write command`,其只能在master redis isntance`上被调用。`因为该命令调用存在side effect,该side effect会对consumer group造成修改 +- `XREADGROUP`为一个`write command`,其只能在master redis instance上被调用。因为该命令调用存在side effect,该side effect会对consumer group造成修改 + +> 在使用XREADGROUP命令时, 只有当传递的id为`>`时,才会对consumer group的last ID造成修改。否则,只会读取pending messages history,并不会实际的修改last ID。故而,当consumer实例重启进行XREADGROUP pending messages时,并不会触发side effect对其他consumers的消费造成影响。 如下示例为一个Ruby实现的consumer, ```ruby @@ -1852,3 +1857,70 @@ redis consumer group对`permanently fail`的场景提供了专门的特性,支 ```redis-cli XPENDING [[IDLE ] []] ``` +如上述示例所示,可以为`XREADGROUP`命令指定如下内容: +- `start-id`和`end-id`: 可以将其指定为`-`和`+` +- `count`: 用于控制该command返回information的数量 +- `consumer-name`: 该选项为optional的,指定该选项后,仅会输出`messages pending for a given consumer` + +为`XPENDINGS`命令指定更多选项的示例如下所示 + +```redis-cli +> XPENDING race:italy italy_riders - + 10 +1) 1) "1692632647899-0" + 2) "Bob" + 3) (integer) 74642 + 4) (integer) 1 +2) 1) "1692632662819-0" + 2) "Bob" + 3) (integer) 74642 + 4) (integer) 1 +``` +在上述示例中,会输出`details for each message`,具体包含如下信息: +- `ID`: message id +- `consumer name`: 该pending message对应的consumer +- `idle time in milliseconds`:代表该message被传递给consumer后,经过的毫秒数 +- `the number of times that a given message was delivered`: 该消息已经被传递的次数 + +在上述示例中,返回的两条`pending messages`都是针对`Bob`的,并且两条消息都被传递了超过一分钟,都只被传递过一次。 + +###### checking the message content +在获取到message detail后,可以根据message ID来查询message的内容,只需将message ID同时作为`XRANGE`命令的`start-id`和`end-id`即可。示例如下所示: +```redis-cli +> XRANGE race:italy 1692632647899-0 1692632647899-0 +1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" +``` + +通过上述介绍的命令,可以制定`permanently fail`场景下的处理策略: +- 当Bob存在超过一分钟都没有处理的pending messages时,Bob可能无法快速被恢复,此时Alice可以针对Bob的pending messages进行`claim`,并且代替Bob对pending messages进行处理 + +###### XCLAIM +`XCLAIM`命令的形式如下: +```redis-cli +XCLAIM ... +``` +XCLAIM命令的作用如下: +- 对于``和``所指定的stream和consumer group,希望将``所指定的message都能更改ownership,将messages分配给``所指定的consumer。 +- 除此之外,我们还提供了``,仅当指定message的`idle time`比指定的`min-idle-time`更大时才有效 + - 指定`min-idle-time`在多个clients尝试同时对message进行claim时会起作用,当第一个client对message进行claim后,idle-time会重置,故而当第二个client尝试对message进行claim时,会因不满足min-idle-time的条件而失败 + +作为claim操作的side effect,`claiming a message will reset its idle time and will increment its number of deliveries counter`。 + +XCLAIM的使用示例如下所示: +```redis-cli +> XCLAIM race:italy italy_riders Alice 60000 1692632647899-0 +1) 1) "1692632647899-0" + 2) 1) "rider" + 2) "Royce" +``` +该消息会`claimed by Alice`,此时consumer Alice可以对该message进行处理并ack,即使original consumer恢复失败,pending messages也能够被继续处理。 + +###### JUSTID option +在上述示例中,在成功对message进行`XCLAIM`后,会返回该message本身。可以通过`JUSTID` option来修改返回的结构,在指定该option后,返回内容为`just IDs of the messages successfully claimed`。 + +通过`JUSTID` option,可以降低client和server之间使用的带宽。 + +`claiming并非一定要位于consumer自身的进程中,其也可以被实现在独立的进程中`: +- `可以使用独立的进程来扫描pending messages list,并且将pending messages分配给明显处于活跃状态的consumers` +