主题
Redis 数据结构与底层实现
一句话机制:对外提供 5 种基础类型 + 3 种特殊类型,内部通过
redisObject的type+encoding做多态编码——同一逻辑类型可按数据规模自动切换底层结构,用户无感。
不变量(必须成立的约束)
- 5 种基础类型:
String / List / Hash / Set / ZSet(有序集合)。 - 3 种特殊类型:
Bitmaps / HyperLogLog / Geospatial—— 它们不是新底层结构,而是基于 String 的封装(Bitmap=位操作 String,GEO 用 ZSet 存经纬度分值)。 redisObject多态:类型检查 + 编码多态;encoding决定底层结构,小数据用紧凑编码、大数据升级为高级结构。- Hash/List/Set/ZSet 元素过多或过大时触发编码升级(如 ZSet 小用
ziplist,大用skiplist + dict)。
关键证据 / 例子
- 底层数据结构:SDS(简单动态字符串)、ZipList(压缩列表)、QuickList(快表)、Dict(哈希表)、IntSet(整数集)、SkipList(跳表)。
- 特殊类型用途:Bitmap 做签到/活跃用户(位运算 + 交集)、HyperLogLog 做独立 UV 基数估算(误差 ~0.81%)、GEO 做附近的人(geohash + ZSet)。
- bigkey 红线:String > 10KB、集合元素 > 5000 即视为 bigkey;删除用
hscan/sscan/zscan渐进式,勿直接del。
常见误解
- ❌「Bitmaps/HyperLogLog/Geospatial 是三种新数据结构」——错,都是已有结构的封装,不占独立类型位。
- ❌「ZSet 底层就是跳表」——不完全;ZSet 同时用 跳表(按分值排序、范围查询)+ 字典(按成员 O(1) 查分值) 两种结构共存。
- ❌「Hash 能存很多 field 没关系」——Hash 的过期只能设在 key 上不能设在 field 上;且大 Hash 在集群下迁移成本高,需控制规模。
- ❌「用 String 存 JSON 对象最省事」——频繁更新单个字段时,Hash 更省内存、更新更原子;大 value 注意 bigkey。
关联
- 来源:Redis常见面试题(Fcant 多源聚合)
- 相关:Redis技术栈总览、概念卡片:Redis为什么这么快