Redis
内存数据结构存储:缓存、消息队列利器。
Redis
这一课你将能做到
- 理解 Redis 五种数据类型及使用场景
- 用 Redis 做缓存,减少数据库压力
- 用 Redis 实现 Session、计数器、排行榜
为什么要学
数据库查询再快,也要读硬盘、走网络。Redis 把热数据放内存,查询速度比数据库快 100 倍。登录态、验证码、热点文章、排行榜,这些高频访问的数据都适合放 Redis。
人话:Redis 是「前台快递柜」,常用包裹放这里,不用每次都跑去大仓库(数据库)。
先建立图像
传统架构:
浏览器 → 后端 → 数据库(慢,10-100ms)
加缓存:
浏览器 → 后端 → Redis(快,1ms)
↓(缓存未命中)
数据库
跟着做
步骤 1:安装与启动
# macOS
brew install redis
brew services start redis
# Ubuntu
sudo apt install redis-server
sudo systemctl start redis
# 测试连接
redis-cli ping
# 返回 PONG
步骤 2:五种数据类型
# 1. String(字符串):缓存对象、计数器
SET user:1 '{"name":"张三","age":25}'
GET user:1
INCR article:100:views # 文章阅读量 +1
SETEX code:13800138000 300 "123456" # 验证码,5分钟过期
# 2. Hash(哈希):存对象字段
HSET user:1 name "张三" age 25
HGET user:1 name
HGETALL user:1
# 3. List(列表):消息队列、最新列表
LPUSH messages "消息1"
LPUSH messages "消息2"
LRANGE messages 0 9 # 取前10条
# 4. Set(集合):标签、去重
SADD article:100:tags "java" "redis" "后端"
SMEMBERS article:100:tags
SISMEMBER article:100:tags "java" # 判断是否存在
# 5. Sorted Set(有序集合):排行榜
ZADD leaderboard 95 "user:1"
ZADD leaderboard 88 "user:2"
ZADD leaderboard 92 "user:3"
ZREVRANGE leaderboard 0 9 WITHSCORES # 前10名
步骤 3:Node.js 连接 Redis
npm install redis
const redis = require('redis');
const client = redis.createClient({
host: 'localhost',
port: 6379
});
client.on('error', err => console.error('Redis 错误:', err));
await client.connect();
// String 操作
await client.set('user:1', JSON.stringify({ name: '张三' }));
const user = await client.get('user:1');
console.log(JSON.parse(user));
// 设置过期时间(秒)
await client.setEx('code:13800138000', 300, '123456');
// Hash 操作
await client.hSet('user:1', 'name', '张三');
await client.hSet('user:1', 'age', '25');
const userData = await client.hGetAll('user:1');
// 计数器
const views = await client.incr('article:100:views');
步骤 4:缓存模式(Cache Aside)
const pool = require('./db'); // PostgreSQL 连接池
const client = require('./redis'); // Redis 客户端
async function getCourse(id) {
const cacheKey = `course:${id}`;
// 1. 先查缓存
const cached = await client.get(cacheKey);
if (cached) {
console.log('缓存命中');
return JSON.parse(cached);
}
// 2. 缓存未命中,查数据库
console.log('缓存未命中,查数据库');
const result = await pool.query('SELECT * FROM course WHERE id = $1', [id]);
const course = result.rows[0];
if (course) {
// 3. 写入缓存,30 分钟过期
await client.setEx(cacheKey, 1800, JSON.stringify(course));
}
return course;
}
// 更新数据时,删除缓存(而非更新缓存)
async function updateCourse(id, data) {
await pool.query('UPDATE course SET title = $1 WHERE id = $2', [data.title, id]);
await client.del(`course:${id}`); // 删除缓存,下次查询时重建
}