RedisNotes

第 02 章:核心概念与数据模型

zjc 于 2026-01-02 发布

这是《Redis 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本章建立 Redis 的概念地图:key、database、value、TTL、编码、客户端连接与请求模型。这些名词会贯穿全书。

2.1 Redis 的数据视图

Redis 可以被看作一个巨大的 Map:

┌──────────────── Redis Instance ─────────────────┐
│ DB0                                              │
│   "user:1001"      -> Hash                      │
│   "stock:sku:1"    -> String("99")              │
│   "rank:score"     -> ZSet                      │
│   "session:abc"    -> String / JSON, TTL=1800   │
│ DB1 ... DB15                                      │
└──────────────────────────────────────────────────┘

2.2 Key 设计规范

Redis 没有表和库的强模型,key 设计就是“schema”。推荐:

业务:对象类型:ID[:属性]

示例:

shop:product:10001
shop:stock:sku:10001
user:session:9f8c...
rank:activity:2026:score
rate:login:user:1001

命名建议

  1. 使用冒号分层,方便按前缀管理和检索;
  2. 长度控制在几十字节内,语义清晰但不要冗长;
  3. 不要使用随机超长 key;
  4. 版本化破坏性结构:user:profile:1001:v2
  5. 避免一个 key 装下几十万字段的大 Hash。

一个常见误解

Redis 不会按 : 自动建立目录索引。SCAN shop:* 的匹配仍是扫描 key 空间,只是跳过不匹配项。想高效统计对象数量,应使用业务索引集合或外部元数据,而不是频繁 SCAN

2.3 逻辑 DB

默认 DB 数量:

databases 16

客户端连接后默认在 DB0:

SELECT 3
FLUSHDB     # 只清当前 DB
FLUSHALL    # 清所有 DB

多 DB 只是命名空间隔离,不提供权限隔离,也不隔离内存和 CPU。因此:

2.4 Value 类型总览

类型 典型语义 常用命令 场景
String 字符串/整数/二进制 SET GET INCR APPEND 缓存对象、计数、token
Hash 字段到值的映射 HSET HGET HGETALL 对象属性、购物车
List 双端链表/快速列表 LPUSH RPOP LRANGE 队列、时间线
Set 无序唯一集合 SADD SISMEMBER SINTER 标签、好友、去重
ZSet 带 score 的有序集合 ZADD ZRANGE ZRANGEBYSCORE 排行榜、延迟队列
Bitmap 位图(String 上操作) SETBIT BITCOUNT 签到、活跃标记
HyperLogLog 基数估算 PFADD PFCOUNT UV 估算
GEO 地理位置 GEOADD GEOSEARCH 附近门店
Stream 消息流 XADD XREAD XGROUP 日志流、事件队列

选型原则:优先贴近业务语义,其次考虑命令复杂度和内存占用。不要把所有数据都 JSON 序列化成 String;也不要为了局部更新一个字段而创建上千个细碎 key。

2.5 TTL 与过期时间

SET session:abc "user-1001" EX 1800
TTL session:abc
EXPIRE session:abc 3600
PERSIST session:abc

要点:

详细机制见第 14 章。

2.6 原子性:Redis 的单线程红利

单条 Redis 命令在服务端串行执行,因此:

INCR counter

不会出现两个客户端同时读到 9、都写回 10 的交错。多个客户端的命令总有一个先后顺序。

但这不等于“多命令事务”:

INCR a
INCR b

两条命令之间可能插入其他客户端命令。要保证原子执行,需要:

见第 9 章。

2.7 RESP 协议与请求模型

客户端与 Redis 使用 RESP(REdis Serialization Protocol)通信。简化过程:

Client                          Redis
  | --- 命令文本/RESP 请求 ------> |
  |                             解析命令
  |                             查找 key
  |                             执行命令
  | <------ RESP 响应 ------------ |

RESP2 常见响应类型:

RESP3 新增 map、double、boolean、push 等类型,让客户端可以拿到更丰富的语义,例如连接中断 push、哈希字段值类型提示。

2.8 Redis 的线程模型概览

Redis 6.0 之前通常被称为“单线程”,更准确地说:

io-threads 4
io-threads-do-reads yes

因此,即使开启 IO 多线程,慢命令依然会阻塞整个实例。线程模型细节见第 15 章。

2.9 持久化与高可用概念速览

概念 作用
RDB 定期生成内存快照,恢复快、文件小
AOF 记录写命令,丢失窗口更小
混合持久化 RDB 头 + 增量 AOF,兼顾恢复速度与数据安全
主从复制 建立副本,读写分离与灾备
Sentinel 自动故障检测与主从切换
Cluster 分片、横向扩容、去中心化路由

这些机制分别在第 16-19 章展开。

2.10 与 MySQL 的概念对照

MySQL Redis 差异
Database/Table 逻辑 DB / key 前缀 Redis 无严格 schema
Row key-value Redis value 是结构
Column Hash field Hash 更适合局部字段更新
Index Set/ZSet/业务索引 需业务自己维护
SQL Redis 命令 无 join/复杂查询
Transaction MULTI/Lua 能力有限,非 SQL 事务
主从复制 replication Redis 常见异步复制

把 Redis 当“可远程访问的内存数据结构服务”,比当“更快的 MySQL”更准确。

本章小结

思考题

  1. 为什么不建议所有对象都序列化成 JSON 字符串存 String?
  2. 如果要更新用户资料的昵称字段,String JSON 和 Hash 哪个更合适?为什么?
  3. SCAN user:* 会不会因为使用了 : 分层而变得高效?为什么?