Redis data
Redis 数据类型
1. String 类型
含义
- Redis 中最基本的数据类型,字符串不仅可以存储普通字符串,还可以存储数字(整数、浮点数)以及二进制数据(如图片、音频等)
- 每个 String 类型的值最大为 512 MB
底层实现原理
- 简单动态字符串(SDS):Redis 中的字符串是基于 SDS 实现的,而不是 C 语言的
char*
- SDS 支持动态扩容,当字符串长度发生变化时会自动调整空间
- SDS 结构包含了字符串长度信息,避免了 C 字符串以
\0
结尾导致的性能问题
- 如果存储的是整数,Redis 可能会使用整数编码优化存储
常见场景
- 缓存数据:存储简单的键值对,如用户配置、网页 HTML 内容等
- 计数器:如页面浏览量(PV)、点赞数等,使用
INCR
或INCRBY
操作 - 分布式锁:通过
SET key value NX EX seconds
实现分布式锁 - 存储二进制数据:如图片、音频等文件的小片段
2. Hash 类型
含义
- 用于存储键值对集合的结构,适合存储对象(如用户信息)
- 每个
Hash
键对应一个字段和值的集合,支持字段级别操作
底层实现原理
- 小型 Hash:
- 使用 ziplist(压缩列表) 存储:当字段数量少于
hash-max-ziplist-entries
(默认 512),且每个字段值小于hash-max-ziplist-value
(默认 64 字节)
- 使用 ziplist(压缩列表) 存储:当字段数量少于
- 大型 Hash:
- 使用 hashtable(哈希表) 存储:当字段数量或字段值超过阈值时,自动转为哈希表
常见场景
- 存储对象信息:如用户资料(
user:id -> name, age, email
) - 减少内存消耗:通过将多个属性存储在一个 Hash 中,减少 Redis 键的数量
- 数据分析:存储统计信息,例如用户行为(
user:stats -> views, clicks
)
3. List 类型
含义
- 一个有序的链表,可以在头部(
LPUSH
)或尾部(RPUSH
)插入数据,支持按索引读取(LINDEX
) - 适合存储有序的数据集合
底层实现原理
- 小型 List:
- 使用 ziplist(压缩列表):当列表元素数量少于
list-max-ziplist-entries
(默认 512),且每个元素小于list-max-ziplist-value
(默认 64 字节)
- 使用 ziplist(压缩列表):当列表元素数量少于
- 大型 List:
- 使用 quicklist(快速列表),是一种压缩列表和双向链表的混合体,既支持快速插入删除,又节省内存
常见场景
- 任务队列:如消息队列、异步任务(
LPUSH
/BRPOP
实现) - 时间序列数据:如日志记录、用户活动记录等
- 排行榜:按时间排序的数据集合
4. Set 类型
含义
- 无序的集合,支持自动去重,常用于存储唯一值
- 提供交集、并集、差集操作
底层实现原理
- 小型 Set:
- 使用 intset(整数集合):当集合内的元素均为整数且数量较少(默认小于 512)
- 大型 Set:
- 使用 hashtable(哈希表):当集合数量较多或包含非整数元素时
常见场景
- 标签系统:存储用户的兴趣标签(
user:tags -> tag1, tag2
) - 好友关系:如共同好友(交集)、推荐好友(差集)
- 去重功能:如统计唯一用户 IP、唯一行为事件
5. Sorted Set 类型
含义
- 有序集合,类似于 Set,但每个元素关联一个 分数(score),通过分数排序
- 适合存储需要排序的数据
底层实现原理
- 使用 跳表(SkipList) 和 hashtable 实现:
- 跳表用于实现按分数排序
- 哈希表用于快速查找元素
常见场景
- 排行榜:如游戏排名、文章热度
- 延时任务:通过分数表示执行时间,按时间顺序取任务
- 日志记录:排序存储用户行为日志,按时间戳排序
6. Bitmap 类型
含义
- 位数组,用于存储二进制数据,每个位(bit)表示一个状态(0 或 1),适合存储大量布尔值
底层实现原理
- 基于 字符串(String) 实现,按位操作,通过偏移量存储每个位的数据
常见场景
- 签到功能:如用户每日签到(1 表示已签到,0 表示未签到)
- 活跃用户统计:记录某段时间内的活跃用户
- 大规模状态存储:如在线状态、是否完成任务等
7. HyperLogLog 类型
含义
- 一种概率性数据结构,用于基数统计(不精确,但节省内存)
- 可统计数十亿数据中不重复的元素个数,误差率约为 0.81%
底层实现原理
- 基于 HyperLogLog 算法:
- 使用固定的 12 KB 内存存储分桶结构
- 通过哈希函数将数据分散到多个桶,统计桶中的最大值估算基数
常见场景
- UV 统计:统计网站的日活跃用户数
- 去重统计:如统计广告点击的去重用户
- 大规模数据分析:如统计日志中的唯一 IP
8. Geospatial 类型
含义
- 用于存储地理位置信息,支持基于经纬度的距离计算和范围查询
底层实现原理
- 基于 Sorted Set 实现:
- 使用 GeoHash 算法将地理坐标编码为一个整数值
- 分数表示坐标值,跳表支持排序和范围查询
常见场景
- LBS 服务:如查找附近的人、附近的商家
- 路径规划:计算两个位置之间的距离
- 物流配送:确定配送范围内的订单
9. Stream 类型
含义
- 用于处理消息队列,类似于 Kafka 的消息流,支持多生产者、多消费者
- 支持消息持久化、分组消费、消费确认
底层实现原理
- 基于 双向链表 和 Radix Tree(压缩树) 实现:
- 消息 ID 是时间戳 + 序列号,保证全局唯一性
- 使用 Radix Tree 高效存储和检索
常见场景
- 日志处理:如实时日志采集、用户行为分析
- 消息队列:构建轻量级的消息队列系统
- 事件流:如订单状态流转、实时监控数据
总结
数据类型 | 含义 | 底层实现 | 常见场景 |
---|---|---|---|
String | 基本键值对存储 | SDS | 缓存、计数器、分布式锁 |
Hash | 存储对象属性 | Ziplist/Hashtable | 用户信息、统计数据 |
List | 有序链表 | Ziplist/Quicklist | 消息队列、时间序列 |
Set | 无序集合,自动去重 | Intset/Hashtable | 标签系统、好友关系、去重 |
Sorted Set | 有序集合,按分数排序 | SkipList | 排行榜、延时任务 |
Bitmap | 位数组,存储布尔值 | String | 签到、状态存储、活跃统计 |
HyperLogLog | 基数统计,支持去重 | HyperLogLog | UV 统计、大规模数据分析 |
Geospatial | 地理位置存储与计算 | GeoHash + ZSet | 附近的人、物流路径规划 |
Stream | 消息队列,支持持久化 | Radix Tree | 日志处理、事件流、消息队列 |
This post is licensed under
CC BY 4.0
by the author.