Redis 数据类型

Redis 的 key 都是字符串,差别在于 value 如何组织。选类型时不用先背命令,只要先判断数据要表达什么。以下结果假设示例 key 原本不存在,各段可以独立运行;数组形式的输出经过了压缩。

基础类型

String:单个值

String 保存文本、数字或二进制数据,适合缓存、计数器和 token。

SET cache:user:1 '{"name":"Hok"}' EX 300 # => OK
GET cache:user:1                            # => {"name":"Hok"}
INCR page:views                             # => 1

如果经常只修改对象中的一个字段,用 Hash 更直接。

Hash:一层对象

Hash 在一个 key 下保存多个 field-value,适合用户资料、商品信息和任务状态。

HSET profile:user:1 name Hok level 3 # => 2
HGET profile:user:1 name             # => Hok
HINCRBY profile:user:1 level 1       # => 4

它适合扁平对象;复杂嵌套结构更适合 JSON 文档或其他数据库。

List:有序序列

List 按插入顺序保存元素,并支持从两端写入或取出,适合简单队列、栈和最近记录。

LPUSH jobs job-1 # => 1
BRPOP jobs 0     # => jobs, job-1

LPUSH history article-1 # => 1
LTRIM history 0 99      # => OK

需要消息确认、消费者组或重放时,改用 Stream。

Set:无序去重集合

Set 保存不重复的成员,适合标签、权限、参与用户和集合运算。

SADD article:1:likes user:1 user:2       # => 2
SISMEMBER article:1:likes user:1         # => 1
SADD user:1:following redis vue          # => 2
SADD user:2:following redis go           # => 2
SINTER user:1:following user:2:following # => redis

Set 不记录顺序;需要排序时使用 Sorted Set。

Sorted Set:按分数排序的集合

Sorted Set 的成员不重复,每个成员带一个 score,适合排行榜、时间线和延迟任务。

ZADD leaderboard 1200 user:1 980 user:2 # => 2
ZRANGE leaderboard 0 9 REV WITHSCORES  # => user:1, 1200, user:2, 980
ZREVRANK leaderboard user:1            # => 0

score 只能直接表达一个数值排序维度。复杂筛选和排序应留在业务层或其他数据库中。

Stream:可消费的消息流

Stream 是追加式消息流,支持消费者组、消息确认和待处理消息追踪,适合轻量异步任务与事件处理。

XADD events 1-0 type order.created order_id 42                       # => 1-0
XGROUP CREATE events workers 0 MKSTREAM                              # => OK
XREADGROUP GROUP workers worker-1 COUNT 10 BLOCK 5000 STREAMS events > # => 消息 1-0
XACK events workers 1-0                                              # => 1

XACK 的 ID 来自 XREADGROUP 返回的消息。跨系统、大规模或需要长期保留的事件流,通常应评估专门的消息系统。

专用类型

Bitmap:布尔状态

Bitmap 是作用于 String 的位操作,适合签到、活跃用户和大量 0/1 状态。

SETBIT attendance:2026-08-26 42 1 # => 0
GETBIT attendance:2026-08-26 42   # => 1
BITCOUNT attendance:2026-08-26    # => 1

offset 需要稳定且相对连续;稀疏 ID 会浪费空间。

Bitfield:紧凑整数

Bitfield 在一个 String 中按指定 bit 宽度读写小整数,适合紧凑保存状态和计数器。

BITFIELD player:1 SET u4 0 7 INCRBY u8 4 1 GET u8 4 # => 0, 1, 1

它节省空间,但字段宽度和 offset 难以维护,只适合结构稳定的场景。

Geospatial Index:附近位置

Geospatial Index 保存经纬度成员,适合附近门店、司机等简单位置查询。

GEOADD stores 113.2644 23.1291 store:1                          # => 1
GEOSEARCH stores FROMLONLAT 113.2644 23.1291 BYRADIUS 5 KM WITHDIST # => store:1, 约 0 km

它不能替代路线规划、多边形分析或完整地图服务。

JSON:嵌套文档

JSON 保存层级化文档,并支持按路径读写,适合嵌套配置和对象缓存。

JSON.SET document:user:1 $ '{"name":"Hok","level":3}' # => OK
JSON.GET document:user:1 $.name                           # => ["Hok"]
JSON.NUMINCRBY document:user:1 $.level 1                  # => [4]

需要复杂条件查询时,还要配合 Redis Search 或使用其他数据库。

Time Series:时间序列

Time Series 保存带时间戳的数值,适合监控指标、设备上报和窗口聚合。

TS.CREATE temperature RETENTION 86400000    # => OK
TS.ADD temperature 1724630400000 26.5       # => 1724630400000
TS.RANGE temperature - +                    # => 1724630400000, 26.5

少量时间排序数据可以用 Sorted Set;需要保留策略、聚合和降采样时再使用它。

Vector Set:向量相似度

Vector Set 保存向量成员并按相似度查询,适合语义搜索、推荐召回和 RAG。

VADD docs VALUES 3 0.1 0.2 0.3 doc:1       # => 1
VSIM docs VALUES 3 0.1 0.2 0.4 COUNT 5     # => doc:1

它从 Redis 8.0 开始提供。向量检索通常只是召回层,最终结果仍要结合权限和业务规则排序。

Array:稀疏索引序列

Array 用整数索引访问字符串值,适合稀疏序列、环形缓冲和按索引读取的数据。

ARSET array:events 0 login click       # => 2
ARGET array:events 1                   # => click
ARSET array:events 1000000 purchase    # => 1

它从 Redis 8.8 开始提供。只需要从两端操作时用 List,需要消费确认时用 Stream。

概率型结构

概率型结构用少量内存换取近似结果,适合统计、预筛和热点发现,不适合作为精确事实来源。

HyperLogLog:估算去重数量

HyperLogLog 估算集合中不同元素的数量,适合统计 UV,但不能返回具体成员。

PFADD page:visitors user:1 user:2 user:3 # => 1
PFCOUNT page:visitors                   # => 约 3

需要精确数量或成员明细时使用 Set 或其他明细存储。

Bloom Filter:判断可能存在

Bloom Filter 用来预判元素是否存在,适合缓存穿透防护和大规模去重。

BF.RESERVE seen:items 0.01 1000 # => OK
BF.ADD seen:items item:1        # => 1
BF.EXISTS seen:items item:1     # => 1

返回“不存在”是确定的,返回“存在”可能误判;它也不支持安全删除单个元素。

Cuckoo Filter:可删除的存在判断

Cuckoo Filter 和 Bloom Filter 类似,但支持删除,适合集合会持续变化的场景。

CF.RESERVE active:items 1000 # => OK
CF.ADD active:items item:1   # => 1
CF.EXISTS active:items item:1 # => 1
CF.DEL active:items item:1   # => 1

它仍然可能误判,容量不足时还会影响写入成功率。

Count-Min Sketch:估算频次

Count-Min Sketch 估算元素出现次数,适合发现热点 key、异常请求和流量趋势。

CMS.INITBYPROB page:freq 0.001 0.01 # => OK
CMS.INCRBY page:freq article:1 3     # => 3
CMS.QUERY page:freq article:1        # => 3

碰撞会让结果偏大,因此不能用于库存、账务等精确计数。

Top-K:发现高频元素

Top-K 估算数据流中出现最频繁的 K 个元素,适合热搜、热门商品和异常流量候选。

TOPK.RESERVE popular 3                 # => OK
TOPK.INCRBY popular redis 3 vue 2 go 1 # => 没有元素被挤出
TOPK.QUERY popular redis mysql         # => 1, 0

需要精确分数和严格排名时使用 Sorted Set。

t-digest:估算分位数

t-digest 估算数值分布的分位数,适合观察延迟、价格和设备指标的 P50、P95、P99。

TDIGEST.CREATE latency                  # => OK
TDIGEST.ADD latency 10 20 30 40 50      # => OK
TDIGEST.QUANTILE latency 0.5 0.95       # => 约 30, 约 50

它不保存可供回放的全部原始样本;需要审计或二次计算时仍要保留明细数据。

完整命令与行为以 Redis Data types 为准。