Redis 使用指南
Redis 是高性能的内存键值数据库,常用于缓存、会话管理和消息队列。
如果你第一次接触 Redis,最重要的不是把所有数据类型都背下来,而是先理解:它为什么快、适合放什么、不适合放什么。
先理解 Redis 适合什么
- 短期缓存
- 会话和验证码
- 排行榜、计数器
- 轻量消息通知
不太适合直接拿来做什么
- 唯一持久化主数据库
- 复杂关系查询
- 没有过期策略的大量临时数据堆积
安装
Docker(推荐)
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- ./redis-data:/data
command: redis-server --appendonly yes
Windows
scoop install redis
# 或使用 Memurai(Windows 原生 Redis 兼容)
winget install Memurai.MemuraiDeveloper
常用命令
# 连接
redis-cli
redis-cli -h 127.0.0.1 -p 6379
# 字符串
SET name "Domi"
GET name
SET token "abc" EX 3600 # 1 小时过期
TTL token # 查看剩余时间
DEL name # 删除
INCR counter # 自增
INCRBY counter 5 # 增加指定值
# 哈希
HSET user:1 name "Domi" age 20
HGET user:1 name
HGETALL user:1
HDEL user:1 age
# 列表
LPUSH queue "task1"
RPUSH queue "task2"
LPOP queue
LRANGE queue 0 -1 # 查看所有
# 集合
SADD tags "vue" "nuxt" "ts"
SMEMBERS tags
SISMEMBER tags "vue"
# 有序集合
ZADD leaderboard 100 "player1" 200 "player2"
ZRANGE leaderboard 0 -1 WITHSCORES
ZREVRANGE leaderboard 0 2 # Top 3
# 通用
KEYS user:* # 查找键(生产慎用)
SCAN 0 MATCH user:* COUNT 100 # 安全遍历
EXISTS name
EXPIRE name 60 # 设置过期
TYPE name # 查看类型
DBSIZE # 键总数
FLUSHDB # 清空当前库
Node.js 集成
ioredis
pnpm add ioredis
import Redis from "ioredis";
const redis = new Redis({
host: "127.0.0.1",
port: 6379,
});
// 基础操作
await redis.set("key", "value");
await redis.set("token", "abc", "EX", 3600);
const val = await redis.get("key");
// 哈希
await redis.hset("user:1", { name: "Domi", age: "20" });
const user = await redis.hgetall("user:1");
// 管道(批量操作)
const pipeline = redis.pipeline();
pipeline.set("a", "1");
pipeline.set("b", "2");
pipeline.get("a");
const results = await pipeline.exec();
缓存策略
Cache-Aside
async function getUser(id: string) {
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await db.query("SELECT * FROM users WHERE id = $1", [id]);
await redis.set(`user:${id}`, JSON.stringify(user), "EX", 300);
return user;
}
缓存失效
// 更新时删除缓存
async function updateUser(id: string, data: any) {
await db.query("UPDATE users SET name = $1 WHERE id = $2", [data.name, id]);
await redis.del(`user:${id}`);
}
发布/订阅
// 发布者
await redis.publish("notifications", JSON.stringify({ type: "new_message" }));
// 订阅者
const sub = new Redis();
sub.subscribe("notifications");
sub.on("message", (channel, message) => {
console.log(channel, JSON.parse(message));
});
参考链接
推荐上手顺序
- 学会字符串和过期时间
- 学会哈希和列表
- 理解缓存旁路(Cache-Aside)
- 再看发布订阅和更复杂模式
常见问题
Redis 内存为什么一直涨
通常是键没有设置过期,或者缓存淘汰策略没有配合业务设计好。
为什么明明用了缓存,数据库压力还是很大
可能是命中率不高、TTL 太短、热点键策略不对,或者更新后根本没正确失效。
Redis 能不能直接替代数据库
个别场景可以做主存储,但对大多数业务系统来说,Redis 更适合做缓存和高频短时数据层。
- Redis 文档 — 官方文档
- ioredis — Node.js 客户端
- Redis Insight — GUI 工具
- Docker Compose 常用配置 — 如果你要把 Redis 作为本地服务栈的一部分一起跑