首页/数据/Redis 进阶速查/intset 整数集合与 Set 内存
数据结构与选型42 条

intset 整数集合与 Set 内存

Set 里全是整数且数量不超过 set-max-intset-entries 时用 intset 存储:有序数组加二分查找,内存占用远低于哈希表。

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

整数集合的紧凑编码

当集合中所有成员都是整数、且数量不超过 set-max-intset-entries(默认 512)时,Redis 会用 intset 存储:把元素按数值升序放在一段连续内存里,查找走二分。相比哈希表实现,每个成员省掉了指针与哈希桶的开销,小集合上的内存差距相当明显。但两个条件任一被打破,编码就会永久转换为 hashtable,而且不会自动转回来。

基本信息

编码路径intset 转换为 hashtable,单向
阈值set-max-intset-entries,默认 512
查找方式有序数组上的二分查找
转换触发插入非整数成员,或成员数超出阈值
查看方式OBJECT ENCODING 返回 intset 或 hashtable

典型使用场景

  • 用集合存用户 ID、设备 ID 等纯整数标识,确认编码是否仍是 intset
  • 内存敏感场景评估整数集合相对哈希表能省多少
  • 上线前评估是否有非整数成员会污染编码
  • 排查集合内存突然上升:编码已经从 intset 转成 hashtable
  • 调阈值之前先量化单键占用的变化

查看与触发

查看与触发
redis-cli SADD ids 101 102 103
redis-cli OBJECT ENCODING ids        # intset
redis-cli MEMORY USAGE ids           # 量化占用,便于前后对比
redis-cli SADD ids abc               # 插入非整数成员
redis-cli OBJECT ENCODING ids        # 已经变成 hashtable
redis-cli CONFIG GET set-max-intset-entries

触发转换的条件

条件结果说明
成员数超出阈值转 hashtable默认 512,可按内存与操作特征调整
插入非整数成员永久转 hashtable删掉该成员也不会转回
成员超出 64 位整数范围转 hashtable超大数值不被视为整数成员
新建纯整数集合保持 intset新增元素可能触发数组扩容重排
intset 内部按数值升序存放,插入新元素可能需要整块数组扩容重排,元素越多单次插入要搬动的字节越多。这是它用内存紧凑性换来的代价,元素数量大时要留意插入延迟。
编码转换是单向的:一旦变成 hashtable,即使把非整数成员删掉、成员数降回阈值以内,也不会自动回到 intset,必须把这个键重建一遍。
内存收益可以用 MEMORY USAGE 直接量化:同样规模的纯整数集合,紧凑编码与哈希表编码的差值通常在数倍量级。评估是否要调整阈值时,用真实业务的键做前后对比,比按理论模型估算可靠得多。

易错点

  • 混合存 ID 与字符串的集合按 intset 估算内存,实际早已转成 hashtable,容量规划失准
  • 以为删掉非整数成员就能恢复紧凑编码,实际需要重建整个键
  • 插入超出 64 位范围的数值触发编码转换,却完全没有察觉
  • 在规模很大的 intset 上做全量操作,忽略它同样受单线程阻塞约束

数据来源与参考

  • Redis 官方文档:Sets 数据类型
  • Redis 源码 intset.c
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌