Redis 基础回顾:数据结构概览、常用命令、键空间与过期策略
在深入缓存契约版本校验之前,必须夯实 Redis 核心基础。本章将系统梳理 Redis 的五大核心数据结构、对应的常用命令、键空间管理机制以及过期策略,为后续的版本号存储、序列化与校验逻辑打下坚实的理论基础。
1. 五大核心数据结构概览
Redis 并非简单的键值存储,其 value 支持多种数据结构。理解每种结构的底层实现与适用场景,是设计高效缓存契约的关键。
| 数据结构 | 底层编码(主要) | 最大元素数 | 典型应用场景 |
|---|---|---|---|
| String | int / embstr / raw | 512 MB | 缓存版本号、计数器、JSON 序列化对象 |
| Hash | ziplist / hashtable | 2^32 - 1 个 field | 存储对象字段级版本、结构化缓存 |
| List | quicklist | 2^32 - 1 个元素 | 消息队列、版本变更日志 |
| Set | intset / hashtable | 2^32 - 1 个元素 | 标签去重、版本白名单 |
| Sorted Set | ziplist / skiplist | 2^32 - 1 个元素 | 版本号排序、时间窗口校验 |
契约提示: 在版本校验场景中,Hash 结构最适合存储带有多个版本字段的缓存对象(如
contract:v1:user:123),而 String 则适合存储单一的全局版本号。
2. 常用命令速查
以下命令是日常操作与版本校验中的高频指令,按数据结构分类整理。
2.1 通用命令(键空间操作)
EXISTS key— 检查键是否存在,返回 1 或 0。TYPE key— 返回键存储的数据结构类型。DEL key [key ...]— 删除一个或多个键。EXPIRE key seconds— 设置键的生存时间(秒)。TTL key— 查看键剩余的生存时间(秒)。RENAME key newkey— 重命名键。
2.2 String 命令
SET key value [NX|XX] [EX seconds]— 设置值,支持条件与过期。GET key— 获取值。MGET key [key ...]— 批量获取。INCR key— 原子自增 1,常用于版本号递增。GETSET key value— 设置新值并返回旧值。
2.3 Hash 命令
HSET key field value— 设置单个字段。HGET key field— 获取单个字段。HMSET key field value [field value ...]— 批量设置。HGETALL key— 获取所有字段与值。HEXISTS key field— 检查字段是否存在。HDEL key field [field ...]— 删除字段。
2.4 其他结构常用命令
| 结构 | 命令示例 | 说明 |
|---|---|---|
| List | LPUSH / RPUSH / LPOP / RPOP / LRANGE |
队列操作,支持阻塞版本 BLPOP |
| Set | SADD / SMEMBERS / SISMEMBER / SINTER |
集合运算,适合版本交集校验 |
| Sorted Set | ZADD / ZRANGE / ZREVRANGE / ZSCORE |
按分数排序,版本号可作为 score |
# 示例:使用 Hash 存储契约版本信息
HSET contract:user:1001 version 2.1.0 data "{...}" updated_at 1700000000
HGET contract:user:1001 version
# 返回 "2.1.0"
3. 键空间(Keyspace)与过期策略
Redis 的键空间是一个全局字典,所有键都存储在其中。理解键空间的扫描与过期机制,对于避免版本校验中的性能陷阱至关重要。
3.1 键空间扫描
KEYS pattern— 阻塞式扫描,返回所有匹配的键。生产环境禁止使用,会阻塞单线程。SCAN cursor [MATCH pattern] [COUNT count]— 游标式增量迭代,无阻塞,适合版本键的批量发现。
性能警告: 在版本校验中,如果需要查找所有以
contract:v2: 开头的键,必须使用 SCAN 而非 KEYS。单次 KEYS 在百万级键空间下可能导致 Redis 服务中断。
3.2 过期策略
Redis 使用三种策略组合来清理过期键:
- 被动过期(惰性删除): 当客户端访问一个键时,检查其是否过期,若过期则删除并返回 nil。
- 主动过期(定期删除): 每 100ms 随机抽取一部分设置了过期时间的键,检查并删除过期键。
- 内存淘汰(eviction): 当内存达到
maxmemory限制时,根据淘汰策略(如 LRU、LFU、TTL)删除键。
在缓存版本校验中,过期策略直接影响版本数据的生命周期:
- 使用
EXPIRE或SET EX为缓存版本设置 TTL,确保旧版本自动失效。 - 避免大量键在同一秒过期(雪崩),可在 TTL 上增加随机偏移量。
- 内存淘汰策略建议使用
allkeys-lru或volatile-lru,防止版本数据占满内存。
# 设置版本缓存,10分钟后过期
SET contract:version:user:1001 "2.1.0" EX 600
# 查看剩余生存时间
TTL contract:version:user:1001
# 返回 598(秒)
4. 数据结构与过期策略关系图
下图展示了 Redis 内部键空间、数据结构编码与过期机制之间的协作关系:
5. 版本校验中的键空间设计建议
最佳实践:
- 命名规范: 使用
contract:{version}:{entity_type}:{entity_id}格式,便于 SCAN 匹配。 - 过期时间: 版本缓存 TTL 建议设置为业务容忍的最大延迟时间 + 随机偏移(如 600 + random(0, 120) 秒)。
- 批量操作: 使用
MGET/HMGET减少网络往返,避免在版本校验循环中逐条 GET。 - 避免大键: 单个 String 值超过 10 KB 时,考虑拆分为 Hash 字段,降低序列化开销。