首页/数据/Redis 进阶速查/Stream 消息写入:XADD 与 ID 规则
数据结构与选型42 条

Stream 消息写入:XADD 与 ID 规则

Stream 是有序、可持久化、带消费组的消息结构:XADD 生成毫秒时间戳-序号 ID,XRANGE/XREVRANGE 按 ID 范围读取,容量用 MAXLEN/MINID 控制。

Redis 进阶速查数据更新于 2026-10-13

XADD 与 Stream 的 ID 规则

Stream 的核心特点是每条消息都有严格递增的唯一 ID,由毫秒时间戳和序号两部分组成,形如 1730020000000-0。XADD 时把 ID 位置写成星号,服务端会自动生成:时间戳取当前毫秒,同一毫秒内的第二条消息序号加一,因此即使服务器时钟出现回拨,ID 也仍然保持单调递增。这种设计让消息天然有序、可按 ID 范围查询,也可以从任意位置回溯。

基本信息

写入XADD key * field value [field value ...]
ID 结构毫秒时间戳-序号,如 1730020000000-0
自动生成用 * 让服务端生成,保证严格递增
容量控制XADD 时可带 MAXLEN 或 MINID 直接裁剪旧数据
读取XRANGE 按 ID 区间正序,XREVRANGE 倒序,XLEN 看条目数

典型使用场景

  • 订单与支付事件流:按写入顺序留痕,可按时间段回溯某个订单的全部事件
  • 替代 List 做队列:获得唯一 ID 与范围查询能力,配合消费组实现确认与重投
  • 审计与操作日志:需要长期保留最近一段时间记录,用 MAXLEN 控制保留窗口
  • 变更通知:下游按 ID 断点续读,重启后从上次位置接着处理
  • 数据管道入湖:把事件先写入 Stream 缓冲,再由采集程序批量取走落库

写入与读取

写入与读取
redis-cli XADD orders '*' item apple qty 2            # 自动生成 ID
redis-cli XADD orders 1730020000000-0 item pear qty 5 # 显式指定 ID 必须大于现有最大 ID
redis-cli XLEN orders                                  # 当前条目数
redis-cli XRANGE orders - + COUNT 10                   # 从最早开始看 10 条
redis-cli XREVRANGE orders + - COUNT 5                 # 最近 5 条
redis-cli XADD orders MAXLEN ~ 100000 '*' item kiwi qty 1   # 写入同时裁剪,近似保留
redis-cli XINFO STREAM orders                          # 看 last-generated-id 与首尾 ID

ID 写法与含义

写法含义使用建议
*由服务端按当前时间自动生成常规写入首选
毫秒时间戳-序号显式指定完整 ID必须大于现有最大 ID,否则报错
毫秒时间戳-*指定时间戳,序号自动生成批量补录同一时刻的数据
-表示最小 IDXRANGE 的起始参数
+表示最大 IDXRANGE 的结束参数
时钟回拨的处理:服务器时间往回跳时,自动生成的 ID 不会小于已有最大 ID,服务端会在序号上递增以保证单调。代价是这些消息记录的时间戳不再准确,对时间敏感的分析场景应记录独立的时间字段而不是只依赖 ID。
不限制长度会无限增长:Stream 的条目默认永久保留,只有配置 MAXLEN 或 MINID 才会裁剪。长期运行且写入频繁的流必须由写入方直接带上裁剪参数,否则内存会被慢慢吃满。

易错点

  • 写入时不带 MAXLEN,条目持续累积直到内存耗尽,应在 XADD 时就明确保留窗口
  • 显式指定 ID 时小于等于现有最大 ID,命令直接报错,补录数据前需要先查看 last-generated-id
  • 用 XRANGE 全量读取超大 Stream 而不加 COUNT,单次返回巨量数据既拖慢服务端也占满客户端内存
  • 把 ID 当成精确的时间来源做统计分析,时钟回拨时时间戳不再可靠,应单独记录业务时间字段

数据来源与参考

  • Redis 官方文档:XADD 命令 / Stream 数据类型
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌