Redis 8.6新特性介绍(2):流的幂等生产机制¶
Tip
在Redis
8.6之前,如果流的生产者客户端在接收到XADD命令的返回值之前掉线了,那么它将无法确定命令发送的消息是否成功,而处理这种情况的通常做法是再次发送相同的消息。
但这样一来,如果服务器之前已经接收到该客户端发送的消息了,只是客户端并未成功接收到服务器返回的回复(消息的ID),那么重复发送相同消息将导致服务器包含两条重复的消息。
+--------+ +--------+
| | -- XADD s * "k1" "v1" --> | |
| | X-- msg_id_1 ------- | |
| Client | | Server |
| | -- XADD s * "k1" "v1" --> | |
| | <------- msg_id_2 ------- | |
+--------+ +--------+
图示:重复发送相同消息的情况
为了解决这个问题,Redis
8.6为流添加了幂等生产机制,以此来保证“同一条消息最多只投递一次”。为了启用这种机制,用户需要在执行XADD命令的时候,使用可选的IDMP选项或是IDMPAUTO选项,并提供相应的生产者标识符(pid)和幂等标识符(iid):
XADD key [IDMP pid iid | IDMPAUTO pid]
<*|id> field value [field value] [...]
注意
IDMPAUTO选项可以根据消息的内容自动生成幂等标识符,但由于该选项对于内容相同的消息总是生成相同的幂等标识符,所以如果你确实有需要发送相同的消息,那么请务必使用IDMP选项而不是IDMPAUTO选项。
与此对应的是,Redis服务器在每次执行带IDMP/IDMPAUTO选项的XADD命令之后,会将被执行命令的pid和iid存储起来,并在之后每次收到带IDMP/IDMPAUTO选项的XADD命令时,检查给定的(pid,
iid)对是否存在:
如果存在则表示该消息最近已经接收过,服务器将返回对应的已存在消息的ID为结果;
如果不存在则表示该消息应该是一条新消息,服务器将为其创建并返回新ID为结果。
+--------+ +--------+
| | -- XADD s IDMP 10086 123 * "k1" "v1" --> | |
| | X-- msg_id_1 ------- | |
| Client | | Server | (pid, iid):
| | -- XADD s IDMP 10086 123 * "k1" "v1" --> | | (10086, 123)->msg_id_1
| | <--------------- msg_id_1 -------------- | |
+--------+ +--------+
图示:未重复发送消息的情况
最后,为了控制被存储的(pid, iid)对数量,Redis
8.6还引入了新的设置命令:
XCFGSET key [IDMP-DURATION seconds] [IDMP-MAXSIZE num]
其中IDMP-DURATION用于设置每个iid的最长存储秒数,而IDMP-MAXSIZE则用于设置每个客户端(也即是对应每个pid)能够保存的最近iid数量。
好的,关于Redis 8.6版本新引入的流的幂等生产机制今天就介绍到这里,感谢大家的观看和阅读~
喜欢这篇博文/这个视频的话欢迎大家给我点赞和关注,谢谢!
扩展阅读
Redis 8.6新版发布官方博文:https://redis.io/blog/announcing-redis-86-performance-improvements-streams/
XADD命令文档:https://redis.io/docs/latest/commands/xadd/
XCFGSET命令文档:https://redis.io/docs/latest/commands/xcfgset/