Redis 键(Key)全攻略
键是 Redis 的基石 —— 掌握键的设计、操作、管理、过期、遍历、命名规范,你就掌握了 Redis 的“命脉”。
一、键(Key)是什么?
Redis 所有数据都以
Key-Value形式存储Key是 字符串类型,唯一标识一条数据。
SET user:1001:name "张三" → key = "user:1001:name"
HSET user:1001 age 25 → key = "user:1001"
二、键的命名规范(生产必备!)
| 规则 | 示例 | 说明 |
|---|---|---|
| 模块:对象:ID:字段 | user:1001:name | 清晰可读 |
使用冒号 : 分隔 | order:20251112:status | 层次分明 |
| 避免特殊字符 | user@1001 → 错误 | 仅限 a-z 0-9 _ - : . |
| 长度控制 < 100 字节 | 过长影响性能 | 建议 < 50 字符 |
| 语义化命名 | cache:article:1001 | 便于运维 |
推荐命名模板
| 场景 | 命名模板 |
|---|---|
| 用户信息 | user:{uid} |
| 用户字段 | user:{uid}:name |
| 会话 | sess:{token} |
| 缓存 | cache:{type}:{id} |
| 排行榜 | rank:{game}:{date} |
| 分布式锁 | lock:{resource}:{id} |
| 临时数据 | tmp:job:{id} |
三、键的常用操作命令
| 命令 | 说明 | 示例 |
|---|---|---|
EXISTS key | 是否存在 | EXISTS user:1001 → 1 |
DEL key [key ...] | 删除 | DEL user:1001 temp:1 |
EXPIRE key seconds | 设置过期(秒) | EXPIRE cache:1 3600 |
PEXPIRE key ms | 毫秒级过期 | PEXPIRE lock:1 30000 |
TTL key | 剩余时间(秒) | TTL cache:1 → 3500 |
PTTL key | 剩余时间(毫秒) | PTTL lock:1 |
PERSIST key | 移除过期 | PERSIST cache:1 |
RENAME key newkey | 重命名 | RENAME old new |
RENAMENX key newkey | 不存在才重命名 | RENAMENX a b |
TYPE key | 返回数据类型 | TYPE user:1001 → hash |
OBJECT ENCODING key | 内部编码 | OBJECT ENCODING list:1 → ziplist |
四、键的过期机制(TTL)
1. 设置过期
SET cache:article:1 "content" EX 3600 # 1小时
SET lock:order:1 "ok" PX 30000 # 30秒
2. 过期策略
| 策略 | 说明 |
|---|---|
| 定时删除 | 创建定时器,过期立即删 → CPU 压力大 |
| 惰性删除 | 访问时才检查 → 内存可能浪费 |
| 定期删除 | 每隔一段时间清理 → Redis 实际采用 |
Redis 结合 惰性 + 定期删除,内存友好
五、键的遍历(慎用 KEYS!)
错误做法(生产禁用)
KEYS * → O(N),阻塞服务器!
KEYS user:* → 大数据量会卡死
正确做法:SCAN 渐进式遍历
SCAN 0 MATCH user:* COUNT 100
# 返回: 1) "12345" 2) 1) "user:1001" 2) "user:1002" ...
SCAN 优势:
- 非阻塞
- 可控速度(
COUNT) - 支持通配符
实战:安全删除所有缓存
# Python 示例(推荐)
import redis
r = redis.Redis()
cursor = 0
while True:
cursor, keys = r.scan(cursor, match="cache:article:*", count=100)
if keys:
r.delete(*keys)
if cursor == 0:
break
六、键的空间与管理
查看键数量
DBSIZE → 当前数据库 key 总数
INFO keyspace → 每个 db 的 key 数
切换数据库
SELECT 0 ~ 15 → Redis 默认 16 个 db
生产建议:只用 db0,用命名空间区分
七、键的设计原则(高性能 + 可维护)
| 原则 | 说明 |
|---|---|
| 避免大 key | List/Hash/Set > 10万 元素 → 拆分 |
| 合理过期 | 缓存设置 TTL,防止内存泄漏 |
| 命名空间隔离 | prod:user:1 vs dev:user:1 |
| 键名短而清晰 | u:1001:n → 不如 user:1001:name |
| 避免频繁 SCAN/KEYS | 用业务逻辑管理 |
八、键的内存占用分析
# 查看单个 key 内存
MEMORY USAGE user:1001
# 输出:256 bytes
# 查看所有 key 内存分布(Redis 7.0+)
MEMORY STATS
大 key 排查脚本
redis-cli --bigkeys
# 输出:
# -------- summary -------
# Sampled 100000 keys
# Biggest string found "cache:large" with 10 MB
# Biggest hash found "user:stats" with 50000 fields
九、键的生命周期管理
graph TD
A[创建 SET/HSET/ZADD] --> B{设置过期?}
B -->|是| C[EXPIRE/PX]
B -->|否| D[永久存储]
C --> E[惰性/定期删除]
E --> F[内存释放]
D --> G[手动 DEL / PERSIST]
十、实战案例:键在业务中的应用
| 场景 | 键设计 | 命令 |
|---|---|---|
| 用户登录态 | sess:{token} | SET sess:abc123 "1001" EX 86400 |
| 分布式锁 | lock:order:1001 | SET lock:order:1001 "ok" NX PX 30000 |
| 文章缓存 | cache:article:1001 | SET cache:article:1001 "{json}" EX 600 |
| 排行榜 | rank:game:20251112 | ZADD rank:game:20251112 1500 "p1" |
| 临时任务 | tmp:job:uuid | SET tmp:job:abc EX 3600 |
十一、一键速查表(贴墙必备)
# 键操作
EXISTS k → 1/0
DEL k1 k2 → 删除数
EXPIRE k 3600 → 1小时
TTL k → 剩余秒
TYPE k → string/hash/zset
SCAN 0 MATCH u:* COUNT 100
# 内存
MEMORY USAGE k
INFO keyspace
DBSIZE
十二、常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 内存暴涨 | 未设置 TTL | 批量加过期 |
| 响应卡顿 | 使用 KEYS * | 改用 SCAN |
| 大 key 阻塞 | List 有 100万元素 | 拆分为 list:1:0~10000 |
| 键冲突 | 命名混乱 | 统一命名规范 |
十三、工具推荐
| 工具 | 用途 |
|---|---|
redis-cli --bigkeys | 查找大 key |
redis-cli --scan --pattern "user:*" | 安全遍历 |
| RedisInsight | 图形化查看键、TTL、内存 |
redis-cli MEMORY DOCTOR | 内存诊断 |
完成!你已精通 Redis 键管理!
# 一行命令:查看所有 user 键并设置 1 小时过期
redis-cli --scan --pattern "user:*" | xargs -r redis-cli EXPIRE 3600
下一步推荐:
需要我帮你:
- 生成项目专属键命名规范?
- 分析线上大 key 并给拆分方案?
- 写一个自动清理过期键的脚本?
回复:命名规范 | 大key | 清理脚本 即可!