Redis Stream 数据结构实现原理真的很强

1. 是什么

Stream 是 Redis 5.0 版本专门为消息队列设计的数据类型,借鉴了 Kafka 的 Consume Group 设计思路,提供了消费组概念

同时提供了消息的持久化和主从复制机制,客户端可以访问任何时刻的数据,并且能记住每一个客户端的访问位置,从而保证消息不丢失。

以下几个是 Stream 类型的主要特性。

  • 使用 Radix Tree 和 listpack 结构来存储消息。

  • 消息 ID 序列化生成。

  • 借鉴 Kafka Consume Group 的概念,多个消费者划分到不同的 Consume Group 中,消费同一个 Streams,同一个 Consume Group 的多个消费者可以一起并行但不重复消费,提升消费能力。

  • 支持多播(多对多),阻塞和非阻塞读取。

  • ACK 确认机制,保证了消息至少被消费一次。

  • 可设置消息保存上限阈值,我会把历史消息丢弃,防止内存占用过大。

需要注意的是,Redis Stream 是一种超轻量级的 MQ,并没有完全实现消息队列的所有设计要点,所以它的使用场景需要考虑业务的数据量和对性能、可靠性的需求。

适合系统消息量不大,容忍数据丢失,使用 Redis Stream 作为消息队列就能享受高性能快速读写消息的优势。

2. 修炼心法

每个 Stream 都有一个唯一的名称,作为 Stream 在 Redis 的 key,在首次使用 xadd 指令添加消息的时候会自动创建。

可以看到 Stream 在一个 Redix Tree 树上,树上存储的是消息 ID,每个消息 ID 对应的消息通过一个指针指向 listpack。

Stream 流就像是一个仅追加内容的消息链表,把消息一个个串起来,每个消息都有一个唯一的 ID 和消息内容,消息内容则由多个 field/value 键值对组成。底层使用 Radix Tree 和 listpack 数据结构存储数据。

为了便于理解,我画了一张图,并对 Radix Tree 的存储数据做了下变形,使用列表来体现 Stream 中消息的逻辑有序性。

图片

图 2-31

图 2-31

这张图涉及很多概念,但是你不要慌。我一步步拆开说,最后你再回头看就懂了。

先带你屡下全局思路。

  • Consumer Group:消费组,每个消费组可以有一个或者多个消费者,消费者之间是竞争关系。不同消费组的消费者之间无任何关系。

  • *pel,全称是 Pending Entries List,记录了当前被客户端读取但是还没有 ack(Acknowledge character 确认字符)的消息。如果客户端没有 ack,这个变量的消息 ID 会越来越多。这是一个核心数据结构,用来确保客户端至少消费消息一次。

Stream 结构

Streams 结构的源码定义在 stream.h 源码中的 stream 结构体中。

typedef struct stream {
    rax *rax;
    uint64_t length;
    strea
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值