本文是大数据系列第 40 篇,系统整理 Redis 五大数据类型的核心命令与生产场景选型指南。

完整图文版(含截图):CSDN 原文 | 掘金

通用键操作

在操作具体数据类型前,先掌握与 key 无关的通用命令:

命令时间复杂度说明
EXISTS keyO(1)判断 key 是否存在
DEL key1 [key2…]O(m)删除一个或多个 key,m 为 key 数量
EXPIRE key secondsO(1)设置过期时间(秒)
TTL keyO(1)查询剩余存活时间,-1 永不过期,-2 不存在
TYPE keyO(1)返回 key 的数据类型
KEYS patternO(N)模式匹配查找(生产环境禁用,改用 SCAN)
SCAN cursor [MATCH pattern] [COUNT count]O(N)游标迭代,不阻塞服务
RENAME key newkeyO(1)原子重命名

String(字符串)

String 是最基础的类型,最大存储 512MB,支持二进制安全存储。

常用命令

# 设置值(带过期时间和条件)
SET key "value" EX 60      # 60 秒后过期
SET key "value" NX          # key 不存在时才设置(分布式锁常用)

# 获取
GET key
MGET key1 key2 key3         # 批量获取,减少网络往返

# 原子计数
INCR counter                # +1
INCRBY counter 10           # +N
INCRBYFLOAT price 0.5       # 支持浮点数

# Bitmap 操作
SETBIT sign:uid:20240801 0 1   # 签到
GETBIT sign:uid:20240801 0
BITCOUNT sign:uid:20240801     # 统计签到天数

# 其他
APPEND key " suffix"
STRLEN key
GETSET key newvalue            # 原子读后写

典型场景

  • 缓存SET user:1001 <json> EX 3600
  • 计数器:页面 PV/UV、库存扣减
  • 分布式锁SET lock:resource uuid NX EX 30

List(列表)

双向链表结构,头尾操作 O(1),随机访问 O(N)。

常用命令

LPUSH list 1 2 3 9 4 5     # 从左侧批量压入
RPUSH list a b c            # 从右侧压入
LRANGE list 0 9             # 查看索引 0-9 的元素
LPOP list                   # 弹出左侧第一个元素
RPOP list
BLPOP queue 5               # 阻塞弹出,等待最多 5 秒(消息队列常用)
LLEN list                   # 获取长度
LTRIM list 0 99             # 保留前 100 个元素,超出丢弃
LMOVE src dst LEFT RIGHT    # 原子移动元素

典型场景

  • 简单消息队列LPUSH 生产,BRPOP 阻塞消费
  • 最新动态LPUSH + LTRIM 维护固定长度列表
  • 循环日志:固定长度的滑动窗口日志

Set(集合)

无序、元素唯一。内部自动在 intset(纯整数小集合)和 hashtable 之间切换。

常用命令

SADD tag:redis u1 u2 u3    # 添加成员
SMEMBERS tag:redis          # 获取所有成员(慎用大集合)
SISMEMBER tag:redis u1      # 判断成员是否存在,O(1)
SCARD tag:redis             # 集合大小
SRANDMEMBER tag:redis 3     # 随机取 3 个(不删除)
SPOP tag:redis              # 随机弹出一个

# 集合运算
SUNION set1 set2            # 并集
SINTER set1 set2            # 交集(共同好友)
SDIFF set1 set2             # 差集

SSCAN set1 0 COUNT 100      # 游标迭代大集合

典型场景

  • 共同好友SINTER user:1:friends user:2:friends
  • 抽奖SRANDMEMBERSPOP
  • 标签去重:文章标签、用户兴趣

Sorted Set(有序集合 / ZSet)

每个成员关联一个 score 分值,按分值有序。支持按排名和按分值范围查询。

常用命令

ZADD rank 100 item1 20 item2 30 item3   # 添加成员及分值
ZCARD rank                               # 成员总数
ZSCORE rank item3                        # 查询指定成员分值
ZRANK rank item1                         # 查询排名(从小到大,0起)
ZREVRANK rank item1                      # 从大到小排名

ZRANGE rank 0 9 WITHSCORES              # 按排名升序获取
ZREVRANGE rank 0 9 WITHSCORES           # 按排名降序获取
ZRANGEBYSCORE rank 80 100               # 按分值范围查询
ZINCRBY rank 5 item1                    # 原子增加分值(+5)
ZCOUNT rank 80 100                      # 统计分值范围内的成员数
ZREM rank item2                         # 删除成员
ZREMRANGEBYRANK rank 0 9               # 删除排名范围内的成员

典型场景

  • 排行榜ZINCRBY 更新积分,ZREVRANGE 取 Top N
  • 热搜词:实时更新搜索频次,按频次排序
  • 延迟队列score = 执行时间戳,定时轮询 ZRANGEBYSCORE 取到期任务

Hash(散列)

单个 key 下存储多个 field-value 对,适合存储结构化对象。

常用命令

HSET u:1001 name "wzk" age 27 city "Beijing"   # 批量设置字段
HGET u:1001 name                                 # 获取单个字段
HMGET u:1001 name age                            # 获取多个字段
HGETALL u:1001                                   # 获取所有字段(慎用大对象)
HINCRBY u:1001 age 1                             # 字段原子自增
HEXISTS u:1001 phone                             # 字段是否存在
HLEN u:1001                                      # 字段数量
HDEL u:1001 city                                 # 删除字段
HRANDFIELD u:1001 2                              # 随机获取 2 个字段

典型场景

  • 用户信息HSET user:uid field value,按需读取单个字段,避免反序列化整个 JSON
  • 购物车HSET cart:uid product_id quantity
  • 对象缓存:字段级更新比 String 存 JSON 更高效

数据类型选型速查

场景推荐类型原因
简单 KV 缓存String最通用,支持原子操作
对象属性存储Hash字段级读写,节省序列化开销
消息队列List有序、支持阻塞消费
去重/标签Set天然唯一性,支持集合运算
排行榜/延迟队列Sorted Set按 score 有序,范围查询高效