目录

1、简介

2、Stream内部探索

2.1 Stream 结构

2.2 四个唯一

2.3 消息ID

2.4 消息内容

3、Stream指令

3.1 指令汇总

3.2 XADD

3.2 XTRIM

3.3 XDEL

3.4 XLEN

3.5 XRANGE

3.6 XREVRANGE

3.7 XREAD

3.8 XGROUP CREATE

3.9 XREADGROUP GROUP

3.10 XACK

3.11 XPENDING

3.11 XCLAIM

3.13 XINFO

4、关于Stream优化内存的事情


1、简介


Stream弥补了Redis作为MQ(message queue)技术选型上的不足之处;Redis 5.0发布的Stream相比Pub/Sub模块,Stream支持消息持久化,结合sentinel或cluster使其成为了一个比较可靠的消息队列。尽管我认为它很难成为公司MQ的技术选型产品,但是关于Stream的使用和特性(消费组),仍值得一探究竟。


Stream对标消息队列,因此几乎具备了MQ所有的特性,以下列出Stream所具有的部分特性:

  • 消息顺序存储
  • 消息ID序列化规则生成
  • 消息的遍历
  • 消息阻塞/非阻塞式获取
  • 客户端分组消费消息
  • 消息确认机制
  • 消息异常机制
  • 消息队列监控

在文中也会说到Stream的这些特性。


2、Stream内部探索


2.1 Stream 结构

在探索Stream的内部结构之前,先看一张清晰的Stream结构图:

redis stream 完成后会不会删除_java

如下是关于上图的名词解析:

  • Message Content:消息内容
  • Consumer group:消费组,通过XGROUP CREATE 命令创建,一个消费组可以有多个消费者
  • Last_delivered_id:游标,每个消费组有一个游标,任意消费者读取消息后,游标都会向前移动
  • Consumer:消费者,消费组中的消费者
  • Pending_ids:状态变量,每个消费者会有一个状态变量,用于记录被当前消费者读取,但是并未ack的消息id

2.2 四个唯一

Stream内部维护了一个消息链表,以此使得消息能够具有队列的特性。在Stream中有四个唯一需要了解:

  1. 每个Stream都具有唯一的名称
  2. 每个消息(Message)都具有一个由系统分配或者客户端指定唯一ID
  3. 每个Stream中的消费组(Consumer_Group)具有唯一名称
  4. 每个消费组(Consumer_Group)中的消费者(Consumer)具有唯一名称

2.3 消息ID

Stream的消息ID可以由服务端自动生成,也可以由客户端传入,如下图是自动生成的结构:

redis stream 完成后会不会删除_redis_02

系统自动生成的规则

-

millisecondsTime指的是Redis节点服务器的本地时间,如果存在当前的毫秒时间戳比以前已经存在的数据的时间戳小的话(本地时间钟后跳),那么系统将会采用以前相同的毫秒创建新的ID。

sequenceNumber指的是序列号,在相同的millisecondsTime毫秒下,序列号从0开始递增,序列号是64位长度,理论上在统一毫秒内生成的数据量无法到达这个级别,因此不用担心sequenceNumber会不够用。


客户端显示传入规则

Redis对于ID有强制要求,格式必须是**-**,最小ID为0-1,并且后续ID不能小于前一个ID

2.4 消息内容

Stream的消息内容,也就是图中的Message Content它的结构类似Hash结构,以key-value的形式存在。


3、Stream指令


3.1 指令汇总

Stream的指令根据可以分为两类,分别是消息队列相关指令,消费组相关指令。

消息队列相关指令:

| 指令名称 | 指令作用 |

| — | — |

| XADD | 添加消息到队列末尾 |

| XTRIM | 限制Stream的长度,如果已经超长会进行截取 |

| XDEL | 删除消息 |

| XLEN | 获取Stream中的消息长度 |

| XRANGE | 获取消息列表(可以指定范围),忽略删除的消息 |

| XREVRANGE | 和XRANGE相比区别在于反向获取,ID从大到小 |

| XREAD | 获取消息(阻塞/非阻塞),返回大于指定ID的消息 |

消费组相关指令:

| 指令名称 | 指令作用 |

| — | — |

| XGROUP CREATE | 创建消费者组 |

| XREADGROUP GROUP | 读取消费者组中的消息 |

| XACK | ack消息,消息被标记为“已处理” |

| XGROUP SETID | 设置消费者组最后递送消息的ID |

| XGROUP DELCONSUMER | 删除消费者组 |

| XPENDING | 打印待处理消息的详细信息 |

| XCLAIM | 转移消息的归属权(长期未被处理/无法处理的消息,转交给其他消费者组进行处理) |

| XINFO | 打印Stream\Consumer\Group的详细信息 |

| XINFO GROUPS | 打印消费者组的详细信息 |

| XINFO STREAM | 打印Stream的详细信息 |

3.2 XADD

XADD 用于向Stream 队列中添加消息,如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列。


XADD的指令语法:

XADD key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|ID field value [field value …]

如下通过XADD展示了定义ID的两种方式,具体可以看2.3。

redis stream 完成后会不会删除_redis_03

3.2 XTRIM

XTRIM 用于对Stream的长度进行限定。


XTRIM 的指令语法:

XTRIM key MAXLEN|MINID [=|~] threshold [LIMIT count]

  • MAXLEN 允许的最大长度,如果长度超出则会抛弃队列前面的消息
  • MINID 允许的最小id,从某个id值开始保留,其余的将会被抛弃

redis stream 完成后会不会删除_外链_04

3.3 XDEL

XDEL 用于删除消息。


XDEL 的指令语法:

XDEL key ID [ID …]

redis stream 完成后会不会删除_java_05

3.4 XLEN

XLEN 用于获取Stream 队列的消息的长度。


XLEN 的指令语法:

XLEN key