Skip to content

Redis 数据结构与底层实现

一句话机制:对外提供 5 种基础类型 + 3 种特殊类型,内部通过 redisObjecttype + 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。

关联

最近更新