Redis常见数据类型及使用场景深度解析
一、核心数据类型详解
1.1 字符串(String)
底层实现:简单动态字符串(SDS),支持二进制安全存储
核心特性:
- 最大存储512MB
- 支持原子增减(INCR/DECR)
- 可存储文本、数值、二进制数据
常用命令:
SET key value [EX seconds] # 设置键值及过期时间
GETRANGE key 0-5 # 截取子字符串
INCRBY key 10 # 原子递增
MSET key1 val1 key2 val2 # 批量设置
使用场景:
- 缓存加速:数据库查询结果缓存(如商品详情)
- 分布式锁:通过
SETNX实现资源互斥访问 - 计数器:网站访问量、视频播放量统计
- 会话管理:存储用户Session信息
内存优化:短字符串使用embstr编码,长字符串使用raw编码
1.2 哈希(Hash)
底层实现:ziplist(小数据)或hashtable(大数据)
核心特性:
- 存储键值对集合(类似Java Map)
- 字段级原子操作(HSET/HINCRBY)
- 适合存储对象属性
常用命令:
HSET user:1000 name "Alice" age 25 # 设置字段
HGETALL user:1000 # 获取所有字段
HMGET user:1000 name age # 批量获取
HINCRBY user:1000 balance 100 # 字段原子递增
使用场景:
- 对象存储:用户信息、商品详情(字段级更新)
- 购物车系统:存储商品ID与数量的映射
- 缓存优化:避免大对象序列化开销
内存优化:当字段数>512或值长度>64字节时自动转为hashtable
1.3 列表(List)
底层实现:双向链表(ziplist压缩列表)
核心特性:
- 支持双端操作(LPUSH/RPOP)
- 按索引范围查询(LRANGE)
- 可实现阻塞队列
常用命令:
LPUSH task_queue "order_001" # 左端插入
BRPOP task_queue 0 # 阻塞右端弹出
LRANGE messages 0-9 # 获取前10条
LTRIM logs 10 20 # 截断保留指定范围
使用场景:
- 消息队列:生产者-消费者模型(异步任务处理)
- 最新动态:社交媒体时间线(如微博动态)
- 任务调度:定时任务队列(结合ZRANGEBYSCORE)
性能注意:长列表LINDEX操作时间复杂度为O(n)
1.4 集合(Set)
底层实现:哈希表(无序唯一元素)
核心特性:
- 元素唯一性自动去重
- 支持集合运算(交集/并集/差集)
- 查找效率O(1)
常用命令:
SADD tags "redis" "cache" # 添加元素
SMEMBERS users # 获取所有成员
SINTER group1 group2 # 求交集
SRANDMEMBER lottery 3 # 随机抽取3个元素
使用场景:
- 社交关系:用户关注列表、共同好友
- 去重统计:UV计算、抽奖防重复
- 标签系统:文章标签管理(快速判断标签存在性)
内存优化:小集合使用intset编码,元素>512时转为hashtable
1.5 有序集合(Sorted Set)
底层实现:跳跃表+哈希表(按score排序)
核心特性:
- 元素唯一且有序(按score或字典序)
- 范围查询(ZRANGEBYSCORE)
- 支持按排名操作(ZRANK)
常用命令:
ZADD leaderboard 1000 alice 950 bob # 添加带分数元素
ZRANGE users 0-9 WITHSCORES # 按分数升序取前10
ZREVRANK task 0 # 按分数降序排名
ZREM range logs "error" # 删除指定元素
使用场景:
- 排行榜系统:游戏积分榜、商品销量榜
- 延迟队列:按时间戳处理任务(如订单超时)
- 实时统计:热点文章按访问量排序
性能注意:元素超过10万时建议分片存储
二、高级数据类型
2.1 位图(Bitmap)
实现方式:String类型的位操作
核心场景:
- 用户签到记录(每日1bit)
- 用户状态标记(如在线状态)
示例:
SETBIT sign:20250605 1001 1 # 用户1001签到
BITCOUNT sign:20250605 # 统计当日签到人数
2.2 HyperLogLog
核心特性:基数估算(误差率<0.81%)
使用场景:
- 网站独立访客(UV)统计
- 去重计数(如广告曝光量)
示例:
PFADD article:1001:uv user1 user2 # 添加UV记录
PFCOUNT article:1001:uv # 估算UV总数
2.3 地理空间(Geospatial)
核心特性:存储经纬度,支持距离计算
使用场景:
- 附近的人/地点查询
- 地理围栏(如到达目的地提醒)
示例:
GEOADD locations 116.40 39.90 "Beijing"
GEORADIUS locations 116.40 39.90 10 km # 半径10公里内查询
2.4 流(Stream)
核心特性:消息队列增强版(支持消息ID、消费组)
使用场景:
- 事件溯源
- 日志收集
示例:
XADD orders * product_id 1001 price 999 # 添加消息
XRANGE orders - + COUNT 10 # 获取最新10条
三、数据类型选择指南
| 场景特征 | 推荐类型 | 理由 |
|---|---|---|
| 需要原子计数 | String | INCR/DECR原子操作 |
| 对象属性频繁修改 | Hash | 字段级更新节省内存 |
| 需要快速去重 | Set | 自动去重特性 |
| 排序需求 | Sorted Set | 内置排序能力 |
| 二进制状态统计 | Bitmap | 1bit存储高效 |
| 基数估算 | HyperLogLog | 内存占用极低(12KB/亿元素) |
四、最佳实践
-
内存优化:
- 启用压缩策略(ziplist/max-ziplist-size)
- 定期执行
MEMORY PURGE整理碎片
-
监控指标:
INFO memory # 查看内存使用 MEMORY USAGE key # 单个键内存占用 SLOWLOG # 慢查询分析 -
持久化策略:
save 900 1 # 900秒内1次修改触发RDB appendfsync everysec # AOF每秒同步 -
集群方案:
- Redis Cluster:自动分片(16384个槽位)
- Sentinel:高可用监控
五、典型业务架构示例
电商库存系统
graph LR
A[用户请求] --> B{Redis Cluster}
B --> C[商品库存Hash]
B --> D[分布式锁String]
B --> E[抢购队列List]
C --> F[库存扣减]
D --> G[锁竞争控制]
E --> H[异步处理订单]
通过合理选择数据类型,可将库存扣减延迟控制在1ms内,支撑每秒10万+并发请求。