Redis(十八)——底层数据结构(三)

IntSet(整数集合)

IntSet ​ 是Redis中Set类型 的一种紧凑型内存编码格式,专门用于存储纯整数的小型集合。

复制代码
// Redis 7.0 源码 intset.h
typedef struct intset {
    uint32_t encoding;  // 编码方式:INTSET_ENC_INT16/32/64
    uint32_t length;    // 元素个数
    int8_t contents[];  // 柔性数组,存储实际数据
} intset;

intset结构:
+------------+--------+-------------------+
|  encoding  | length |    contents[]     |
|  (4字节)   | (4字节)|   (可变长度)      |
+------------+--------+-------------------+
                 ↓
实际存储(INTSET_ENC_INT16,存储[1, 2, 3]):
+------------+--------+----+----+----+
|    INT16   |   3    | 1  | 2  | 3  |
|   (0x0002) | (0x0003)|0x01|0x02|0x03|
+------------+--------+----+----+----+
内存占用:4 + 4 + 3 * 2 = 14字节

这个其实和ziplist有点类似,都是连续的内存空间,只是intset只能存整数,而且也只是set的底层结构,没有尾指针,元素中也没有前一个元素的大小,就一个很普通的数组。去重就很简单了,使用二分查找现在的数组中有没有,没有就插入有就不插入了。没错intset是有序的,但是set类型是无序的,无序是set的api体现的,这里就不拆解了哦。如果inset是无序的那么每次增删改查都可能需要全数组遍历,虽然是连续内存但是性能消耗同样很大。

IntSet与Hashtable特性对比

特性 IntSet(整数集合) Hashtable(哈希表)
存储类型 只存整数 任意类型
内存占用 极低(紧凑数组) 较高(指针+entry结构)
查找性能 O(log n) 二分查找 O(1) 平均,O(n) 最坏情况
插入性能 O(n) 需要移动元素 O(1) 平均
删除性能 O(n) 需要移动元素 O(1) 平均
最大元素数 可配置(默认512) 无限制
自动转换 超限或非整数 → hashtable 不会转回intset

Radix Tree(基数树)

Radix Tree (基数树/压缩前缀树)是一种优化的前缀树(Trie),用于高效存储和查找字符串集合。Redis 5.0+ 将其用于Stream类型的底层实现以及Cluster节点配置。

复制代码
// Redis中的Rax(Radix Tree实现)
typedef struct rax {
    raxNode *head;      // 根节点
    uint64_t numele;    // 元素数量
    uint64_t numnodes;  // 节点数量
} rax;

typedef struct raxNode {
    uint32_t iskey:1;     // 是否包含key
    uint32_t isnull:1;    // 关联值是否为NULL
    uint32_t iscompr:1;   // 是否压缩节点
    uint32_t size:29;     // 子节点数量或压缩字符串长度
    unsigned char data[]; // 柔性数组存储数据
} raxNode;

普通前缀树:               Radix树(压缩后):
       r                        r
      / \                      / \
     o   u                  oot  un
    /     \                /       \
   o       n             (ot)      (n)
  /         \           /   \       \
 t*          n*       key1  key2    key3
  ↓           ↓
"root"      "run"

存储: root, rooster, run
压缩节点: "oot", "un"

其实和普通的前缀树的区别就是,假如一个父节点只有一个子节点,那么就把他们两个合并,

https://ivanzz1001.github.io/records/post/data-structure/2018/11/18/ds-radix-tree

这个文章写的非常的清楚,比主包现在讲要好很多,大家可以去看看吧。

Redis 10大数据类型底层结构总结

以下是整理后的Redis数据类型底层结构对比表格:

数据类型 底层结构版本说明 主要特性 使用场景
String 1. SDS (Simple Dynamic String)<br>2. int (整数编码)<br>3. embstr (嵌入式字符串)<br>4. raw (原始SDS) O(1)获取长度,二进制安全 缓存、计数器、session
List 1. quicklist (3.2+)<br>2. ziplist (旧版)<br>3. linkedlist (旧版) 双向遍历,支持阻塞操作 消息队列、最新列表
Hash 1. listpack (7.0+)<br>2. ziplist (7.0前)<br>3. hashtable 字段值映射,适合存储对象 对象存储、商品属性
Set 1. intset (整数集合)<br>2. hashtable 无序唯一集合,支持去重操作 标签、好友关系
ZSet 1. listpack (7.0+)<br>2. ziplist (7.0前)<br>3. skiplist+dict 有序集合,按分数排序,范围查询 排行榜、延迟队列
Stream Radix Tree (基数树) 消息持久化,支持消费者组 消息队列、日志流
Bitmap String (SDS) 位操作,节省空间 用户签到、活跃统计
HyperLogLog 1. sparse (稀疏)<br>2. dense (密集) 固定内存,基数估算误差0.81% UV统计、去重计数
GEO Sorted Set (底层: ziplist/listpack或skiplist+dict) 地理计算,支持半径查询 附近的人、地理位置
Bitfield String (SDS) 位操作,原子性 标志位、紧凑存储

总结

本篇主要总结和介绍intset、radix tree。

相关推荐
冬奇Lab10 小时前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence21 小时前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神1 天前
三、用户与权限管理
数据库·mysql
小小工匠2 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
麦聪聊数据2 天前
数据服务化时代:企业数据能力输出的核心路径
数据库
shushangyun_2 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
DARLING Zero two♡2 天前
【MySQL数据库】数据类型与表约束
数据库·mysql
ofoxcoding2 天前
在AI API聚合平台配置DeepSeek V3.2提示词缓存实战:快速接入与成本优化指南
人工智能·spring·缓存·ai
曹牧2 天前
Oracle EXPLAIN PLAN
数据库·oracle
BD_Marathon2 天前
SQL学习指南——视图
数据库·sql