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  # 批量设置

使用场景

  1. 缓存加速:数据库查询结果缓存(如商品详情)
  2. 分布式锁:通过SETNX实现资源互斥访问
  3. 计数器:网站访问量、视频播放量统计
  4. 会话管理:存储用户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       # 字段原子递增

使用场景

  1. 对象存储:用户信息、商品详情(字段级更新)
  2. 购物车系统:存储商品ID与数量的映射
  3. 缓存优化:避免大对象序列化开销
    内存优化:当字段数>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                    # 截断保留指定范围

使用场景

  1. 消息队列:生产者-消费者模型(异步任务处理)
  2. 最新动态:社交媒体时间线(如微博动态)
  3. 任务调度:定时任务队列(结合ZRANGEBYSCORE)
    性能注意:长列表LINDEX操作时间复杂度为O(n)

1.4 集合(Set)

底层实现:哈希表(无序唯一元素)
核心特性

  • 元素唯一性自动去重
  • 支持集合运算(交集/并集/差集)
  • 查找效率O(1)

常用命令

SADD tags "redis" "cache"           # 添加元素
SMEMBERS users                      # 获取所有成员
SINTER group1 group2                # 求交集
SRANDMEMBER lottery 3               # 随机抽取3个元素

使用场景

  1. 社交关系:用户关注列表、共同好友
  2. 去重统计:UV计算、抽奖防重复
  3. 标签系统:文章标签管理(快速判断标签存在性)
    内存优化:小集合使用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"             # 删除指定元素

使用场景

  1. 排行榜系统:游戏积分榜、商品销量榜
  2. 延迟队列:按时间戳处理任务(如订单超时)
  3. 实时统计:热点文章按访问量排序
    性能注意:元素超过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条

三、数据类型选择指南

场景特征推荐类型理由
需要原子计数StringINCR/DECR原子操作
对象属性频繁修改Hash字段级更新节省内存
需要快速去重Set自动去重特性
排序需求Sorted Set内置排序能力
二进制状态统计Bitmap1bit存储高效
基数估算HyperLogLog内存占用极低(12KB/亿元素)

四、最佳实践

  1. 内存优化

    • 启用压缩策略(ziplist/max-ziplist-size)
    • 定期执行MEMORY PURGE整理碎片
  2. 监控指标

    INFO memory          # 查看内存使用
    MEMORY USAGE key     # 单个键内存占用
    SLOWLOG              # 慢查询分析
    
  3. 持久化策略

    save 900 1           # 900秒内1次修改触发RDB
    appendfsync everysec # AOF每秒同步
    
  4. 集群方案

    • 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万+并发请求。