Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Redis数据结构:Stream类型全面解析

Redis数据结构:Stream类型全面解析

作者头像
栗筝i
发布于 2023-10-16 06:37:04
发布于 2023-10-16 06:37:04
91600
代码可运行
举报
文章被收录于专栏:迁移内容迁移内容
运行总次数:0
代码可运行

Redis,作为一种高性能的键值对数据库,因其丰富的数据类型和高效的性能而受到了广泛的关注和使用。在 Redis 的多种数据类型中,Stream 类型可能是最新,也是最具有挑战性的一种。Stream 类型是 Redis 5.0 版本引入的一种新的数据类型,它提供了一种持久化的、可查询的、可扩展的消息队列服务。 在这篇文章中,我们将全面解析 Redis 的 Stream 类型。我们将从 Stream 的基本概念和特性开始,然后深入到它的内部实现和性能优化。我们还将通过实际的示例来展示如何在实际应用中使用 Stream。无论你是刚接触 Redis,还是已经有一定经验的开发者,我相信你都能从这篇文章中学到一些有用的知识。

1、Stream数据类型
1.1、Stream类型简介

Redis Stream 是 Redis 5.0 版本引入的一种新的数据类型,它是一个持久化的、可查询的、可扩展的消息队列服务。

Stream 类型的数据结构类似于一个日志系统,数据被添加到 Stream 的末尾,并且每个数据都会被分配一个唯一的序列号,这个序列号是按照时间顺序递增的。这使得 Stream 类型非常适合用于实现消息队列、事件驱动的系统、数据流处理等场景。

Stream 类型的主要特性包括:

  1. 持久化:与其他 Redis 数据类型一样,Stream 类型的数据也可以被持久化到磁盘,这意味着即使 Redis 服务器重启,Stream 中的数据也不会丢失。
  2. 消费者组:Stream 类型支持消费者组的概念,这使得多个消费者可以同时从同一个 Stream 中读取数据,每个消费者都会读取到自己还未读取的数据。
  3. 阻塞读取:消费者可以选择阻塞地从 Stream 中读取数据,如果当前没有新的数据,消费者可以选择等待,直到有新的数据到达。
  4. 历史数据查询:消费者可以查询 Stream 中的历史数据,这使得消费者可以在处理完当前的数据后,再处理之前的数据。

以上只是 Stream 类型的一些基本特性,实际上,Stream 类型还有很多其他的特性和用法,可以满足各种复杂的应用场景。

1.2、Stream使用场景

Redis Stream 是一种非常灵活的数据结构,可以应用于多种场景,以下是一些常见的应用场景:

  1. 消息队列:Redis Stream 可以作为一个持久化的、可扩展的消息队列服务,用于在不同的应用组件之间传递消息。消费者可以实时地从 Stream 中读取新的消息,也可以查询历史的消息。
  2. 事件驱动的系统:在事件驱动的系统中,可以使用 Redis Stream 来存储和传递事件。每个事件都可以作为一个 Stream 元素,包含事件的类型、数据和时间戳等信息。
  3. 日志记录:由于 Stream 元素是按照时间顺序存储的,因此 Redis Stream 非常适合用于记录日志。你可以将日志事件作为 Stream 元素,包含日志的级别、消息和时间戳等信息。
  4. 数据流处理:Redis Stream 可以用于实现数据流处理系统。你可以将数据流作为 Stream 元素,然后使用消费者组来并行处理这些数据。
  5. 实时分析:你可以使用 Redis Stream 来收集实时的事件数据,然后实时分析这些数据,例如统计用户的行为、监控系统的状态等。

以上只是 Redis Stream 的一些常见应用场景,实际上,由于其强大和灵活的特性,你可以在很多其他的场景中使用 Redis Stream。


2、Stream底层结构
2.1、Stream底层结构介绍

Redis Stream 的底层数据结构主要由基数树(Radix Tree)和 Listpack 组成。基数树用于索引 Listpack,而 Listpack 用于存储 Stream Entry。

当一个新的 Stream Entry 被添加到 Stream 中时,Redis 会首先尝试将其添加到最新的 Listpack 中。但是,如果这个 Listpack 的大小已经达到了预设的上限(默认为 4096 bytes),那么 Redis 就会创建一个新的 Listpack,并将新的 Stream Entry 添加到这个新的 Listpack 中。

这个新的 Listpack 会被添加到基数树中,其对应的键是新 Stream Entry 的 ID。这样,基数树就可以用于快速定位到包含指定 ID 的 Listpack。

所以,基数树和 Listpack 的转换条件主要是 Listpack 的大小是否达到了预设的上限。如果达到了上限,就需要创建新的 Listpack 并更新基数树。

2.2、Listpack

Listpack:Listpack 是一种紧凑、高效的列表类型,用于存储多个 Stream Entry。每个 Stream Entry 包含以下几个部分:

  1. Entry ID:每个 Entry 都有一个唯一的 ID,它由两部分组成,时间戳和序列号,用于保证每个 Entry 的唯一性。
  2. Field and Value:每个 Entry 包含了多个 Field 和 Value 对,用于存储实际的数据。

在 Redis Stream 的底层实现中,所有的 Stream Entry 都存储在 Listpack 中。每个 Listpack 可以存储多个 Stream Entry,而多个 Listpack 则通过基数树(Radix Tree)进行索引,以便于快速查找。

Listpack 是 Redis 5.0 版本引入的一种新的数据结构,它是为了替代 Ziplist(紧凑列表)而设计的。Listpack 提供了与 Ziplist 类似的功能,但在某些方面进行了优化,以提高效率和可用性。

Listpack 和 Ziplist 都是紧凑、高效的列表类型,用于存储多个条目。但是,Listpack 在以下几个方面进行了优化:

  1. 更大的最大元素数量:Listpack 可以存储的元素数量比 Ziplist 更多。
  2. 更高效的内存使用:Listpack 的内存布局更加紧凑,使得它在存储相同数量的元素时,使用的内存更少。
  3. 更快的操作速度:Listpack 的设计使得插入、删除和查找操作更快。

因此,虽然 Listpack 可以被看作是 Ziplist 的替代版本,但它在很多方面都进行了优化和改进。

每个 Listpack 包含以下几个部分:

  1. Header:包含了一些元数据,如 Listpack 的总字节数(占用 6 字节)和元素数量(占用 2 字节)。如果元素数量超过 65535,这个值就会被设置为 65535,需要通过遍历整个 Listpack 来获取准确的元素数量。
  2. Entries:这是 Listpack 中的主要部分,包含了所有的元素。每个元素都由一个 header 和一个 body 组成。header 包含了元素的长度和编码方式,body 则包含了元素的实际值。
  3. End:标记了 Listpack 的结束,由一个单字节的 0xFF 组成。

每个 Listpack 的元素可以是任意长度的字符串,也可以是整数。整数可以以不同的方式编码,以节省空间。例如,小的整数可以直接以一到四个字节的形式存储,而较大的整数则可以以字符串的形式存储。

Listpack 的设计使得它在存储大量小元素时非常高效,同时也支持在任意位置插入或删除元素。

2.3、基数树

基数树(Radix Tree):基数树是一种高效的键值对存储数据结构,Redis Stream 使用基数树来索引 Listpack。基数树的键是 Stream Entry 的 ID,值是对应的 Listpack。通过基数树,可以快速定位到包含指定 ID 的 Listpack。


3、Stream常用命令

Redis Stream 提供了一系列的命令用于操作和管理 Stream 数据结构,以下是一些常用的命令:

XADD:向 Stream 中添加一个新的 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XADD mystream * sensor-id 1234 temperature 19.8

XRANGE:获取 Stream 中的一系列 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XRANGE mystream - +

XREAD:从 Stream 中读取新的 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XREAD COUNT 2 STREAMS mystream 0

XDEL:从 Stream 中删除指定的 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XDEL mystream 1526569495631-0

XTRIM:裁剪 Stream,只保留指定数量的 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XTRIM mystream MAXLEN 1000

XLEN:获取 Stream 中的 Entry 数量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XLEN mystream

XGROUP:管理 Stream 的消费者组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XGROUP CREATE mystream mygroup 0

XREADGROUP:从消费者组中读取新的 Entry。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XREADGROUP GROUP mygroup Alice STREAMS mystream >

XACK:确认消费者组中的 Entry 已经被处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XACK mystream mygroup 1526569498055-0

以上就是一些常用的 Redis Stream 命令,可以用于管理和操作 Stream 数据结构。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Redis Stream 数据结构实现原理真的很强
Stream 是 Redis 5.0 版本专门为消息队列设计的数据类型,借鉴了 Kafka 的 Consume Group 设计思路,提供了消费组概念。
码哥字节
2023/09/20
5580
Redis Stream 数据结构实现原理真的很强
Redis数据结构:List类型全面解析
Redis 中列表(List)类型是用来存储多个有序的字符串,列表中的每个字符串成为元素 Eelement),一个列表最多可以存储 2^32-1 个元素。
栗筝i
2023/10/16
3.3K0
Redis数据结构:List类型全面解析
Redis源码阅读(二)底层数据结构
Redis对于底层数据结构的极致封装,是Redis高效运行的原因之一。我们结合Redis源码对其进行分析。
星沉
2022/01/28
9190
Redis Stream 实践
stream 是一个日志形式的存储结构,可以往里追加数据,每条数据都会生成一个时间戳ID,stream 也有便捷的读取数据的模型。
dys
2018/08/01
1.3K0
Redis基础教程(十六):Redis Stream
在现代分布式系统中,消息队列和事件驱动架构变得越来越重要,它们在异步处理、解耦服务组件、实现事件驱动的微服务等方面发挥着关键作用。Redis,作为一款多功能的开源数据结构存储系统,自4.0版本开始引入了Stream数据结构,为构建高效的消息队列和事件驱动系统提供了新的可能。本文将深入解析Redis Stream的特性、操作命令,并通过具体案例展示其在实际场景中的应用。
用户11147438
2024/07/12
5990
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列
使用 Redis 实现消息队列 普通的订阅 基于模式(pattern)的发布/订阅 看下源码实现 分析下源码实现 stream 的结构 streamCG 消费者组 streamConsumer 消费者结构 分析下源码实现 基于List的消息队列 基于 Streams 的消息队列 发布订阅 总结 参考 ◆使用 Redis 实现消息队列 Redis 中也是可以实现消息队列 不过谈到消息队列,我们会经常遇到下面的几个问题 1、消息如何防止丢失; 2、消息的重复发送如何处理; 3、消息的顺序性问题; 关于 mq
IT大咖说
2022/03/21
1.3K0
38 张图详解 Redis:核心架构、发布订阅机制、9大数据类型底层原理、RDB和AOF 持久化、高可用架构、性能问题排查和调优
今天我们从全局视角开始,带着问题去寻找答案,梳理 Redis 核心知识点与架构设计:核心架构、String(字符串)、Hashes(散列表)、Lists(列表)、Sets(无序集合)、Sorted Sets(可根据范围查询的排序集合)、Bitmap(位图)、HyperLogLog、Geospatial (地理空间)和 Stream(流)等数据类型底层实现原理、发布订阅机制、RDB、AOF 持久化、主从架构、哨兵集群架构、Cluster 架构、性能优化。(ps:文章内容摘选自我的新书《Redis 高手心法》,更多完整内容详见本书籍)
码哥字节
2025/03/27
3300
38 张图详解 Redis:核心架构、发布订阅机制、9大数据类型底层原理、RDB和AOF 持久化、高可用架构、性能问题排查和调优
Redis 基础数据结构
Redis用到的底层数据结构有:简单动态字符串、双端链表、字典、压缩列表、整数集合、跳跃表等,Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些基础数据结构创建了一个对象系统,这写对象包括字符串对象、列表对象、哈希对象、集合对象和有序集合对象等。
luoxn28
2019/11/06
1.3K0
Redis streams 作为一个纯数据结构
我们在Redis5版本迎来了一个新的数据结构,它的名字叫做"Streams"。(撒花)Streams一经推出,就引起了社区中各位大佬的关注。所以我决定过一段时间做一个社区调查,讨论一下它的使用场景,并会在博客中将结果记录下来(是Redis作者的博客)。今天我想聊的是另一个问题:我怀疑有很多用户认为Streams的使用场景是和Kafka一样的。实际上,这个数据结构的设计背景也是消息的生产和消费,但你应该认为Redis Streams只是更擅长做这样的事情。流是一种很好的模型和"心理模型",它能帮助我们更好的设计系统,但是Redis Streams像其他Redis数据结构一样,它更加通用,可以用来处理更多不同的问题。所以这篇博客我们会重点关注Redis Streams作为一种数据结构有哪些特性,而完全忽略它的阻塞操作、消费群和所有消息相关的内容。
随心助手
2019/10/15
7840
Redis底层数据结构
由图中可知,底层的数据结构有所变化,在Redis7中不再推荐使用ziplist,而是使用listpack代替,但考虑兼容性,目前仍保留ziplist。
用户3876103
2024/08/26
1310
从源码上聊聊Redis-String、List的结构实现
本文的数据类型只讲底层结构和部分机制,不讲具体的使用,使用的话自行bing,但是会提一些应用场景
Karos
2023/07/20
9610
从源码上聊聊Redis-String、List的结构实现
Redis之stream类型解读
Redis stream(流)是一种数据结构,其作用类似于仅追加日志,但也实现了多个操作来克服典型仅追加日志的一些限制。其中包括O(1)时间的随机访问和复杂的消费策略,如消费者群体。 您可以使用流实时记录和同时联合事件。
一个风轻云淡
2023/09/23
4450
[译] Redis Streams介绍
我大学的时候英语6级没过,因此但凡懂点英语的同学,如果你进到此页面,尽量去阅读原文,链接在下方原文地址.最次也要对照着原文阅读,以免我出了什么差错(这是不可避免的),坑了别的小伙伴.
呼延十
2019/07/01
2.1K0
Redis消息队列 | Stream
在RedisV5.0之前, 如果想实现队列功能, 只能用list或者pub/sub实现, 但它们都有自己的缺点.
一个架构师
2022/06/27
1.4K0
redis灵魂拷问:如何使用stream实现消息队列
redis在很早之前就支持消息队列了,使用的是PUB/SUB功能来实现的。PUB/SUB有一个缺点就是消息不能持久化,如果redis发生宕机,或者客户端发生网络断开,历史消息就丢失了。
jinjunzhu
2021/01/05
3.2K0
redis灵魂拷问:如何使用stream实现消息队列
Redis数据结构总结
Redis 本身是一个键值对数据库,这种键值对的存储方式就是哈希映射(Hashmap)的一种体现,即通过键(Key)来快速查找对应的值(Value)。
栗筝i
2023/10/16
3500
Redis数据结构总结
深入剖析 Redis5.0 全新数据结构 Streams(消息队列的新选择)
Redis 5.0 全新的数据类型:streams,官方把它定义为:以更抽象的方式建模日志的数据结构。Redis的streams主要是一个append only的数据结构,至少在概念上它是一种在内存中表示的抽象数据类型,只不过它们实现了更强大的操作,以克服日志文件本身的限制。
芋道源码
2019/10/29
2.1K0
Redis stream 用做消息队列完美吗
Redis Stream 是 Redis 5.0 版本中引入的一种新的数据结构,它用于实现简单但功能强大的消息传递模式。
勇哥java实战
2024/04/15
4470
Redis数据结构:Zset类型全面解析
Zset,即有序集合(Sorted Set),是 Redis 提供的一种复杂数据类型。Zset 是 set 的升级版,它在 set 的基础上增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列。
栗筝i
2023/10/16
9.3K0
Redis数据结构:Zset类型全面解析
Redis高级特性之Pub/Sub与Stream
在Stream之前,Redis PUB/SUB亦可可实现消息的传递及广播,但消息不支持持久化,不记录消费端状态,并且“Fire and Forgot”,可靠性无法保证。
vitofliu
2019/07/03
4K0
相关推荐
Redis Stream 数据结构实现原理真的很强
更多 >
LV.1
这个人很懒,什么都没有留下~
加入讨论
的问答专区 >
1高级后端开发工程师擅长3个领域
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    本文部分代码块支持一键运行,欢迎体验
    本文部分代码块支持一键运行,欢迎体验