结合 PHP、MySQL 和 Redis 如何实现缓存加速?
结合 PHP、MySQL 和 Redis 实现 缓存加速 是 Web 开发中常用的性能优化方案。核心思想是:
- 先查 Redis 缓存
- 缓存命中则直接返回
- 未命中则查 MySQL → 存入 Redis → 返回数据
下面从实战角度来讲解如何实现,并且针对实现代码、架构建议、缓存策略、注意事项等简单介绍。
一、整体架构图
[客户端请求]
↓
[PHP 脚本]
↓
检查 Redis 缓存 → 命中?→ 是 → 返回
↓
否
↓
查询 MySQL 数据库
↓
将数据写入 Redis 缓存(设置过期时间)
↓
返回数据
二、环境准备
1. 安装扩展
- 安装 PHP Redis 扩展:
# Ubuntu/Debian
sudo apt install php-redis
# macOS(使用 brew)
brew install php@8.1-redis
- 安装 Redis 服务:
sudo apt install redis
sudo systemctl start redis
2. 确保连接成功
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
echo $redis->ping(); // 输出 PONG 表示连接成功
三、PHP+MySQL+Redis 缓存示例代码
使用场景:查询用户信息并缓存 60 秒
<?php
// 连接 Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 假设我们要查询 ID 为 1 的用户信息
$userId = 1;
$cacheKey = "user:$userId";
// 1. 检查缓存
if ($redis->exists($cacheKey)) {
// 从 Redis 获取数据
$userData = json_decode($redis->get($cacheKey), true);
echo "来自缓存的数据:\n";
} else {
// 2. 连接数据库
$pdo = new PDO("mysql:host=localhost;dbname=testdb", "root", "password");
$stmt = $pdo->prepare("SELECT id, name, email FROM users WHERE id = ?");
$stmt->execute([$userId]);
$userData = $stmt->fetch(PDO::FETCH_ASSOC);
// 3. 存入缓存(设置过期时间为60秒)
if ($userData) {
$redis->setex($cacheKey, 60, json_encode($userData));
}
echo "来自数据库的数据:\n";
}
// 输出数据
print_r($userData);
四、缓存策略建议
| 策略 | 建议说明 |
|---|---|
| 缓存键设计 | 使用结构化 key,如:user:{id},article:{id} |
| 过期时间 | 常规数据 60-300 秒,热点数据可延长 |
| 缓存失效 | 使用 setex() 或 expire() 明确设定 |
| 缓存雪崩 | 给每个 key 设置不同的过期时间(如加随机数) |
| 缓存穿透 | 查询无结果也缓存一段时间(防止反复击穿) |
| 缓存更新 | 写数据库成功后,更新缓存或延迟异步更新 |
五、扩展:更新缓存策略(写后清缓存)
// 更新用户信息后清除缓存
$stmt = $pdo->prepare("UPDATE users SET name = ? WHERE id = ?");
$stmt->execute(["新名字", $userId]);
// 删除缓存
$redis->del("user:$userId");
六、性能优化点
| 优化点 | 描述 |
|---|---|
| 使用连接池 | 对于 Redis、MySQL 都应使用连接池(如 Swoole/FPM) |
| 热点数据永久缓存 | 设置高优先级数据不清除 |
| 增加异步更新/预热机制 | 避免高并发下缓存穿透 |
| 使用 JSON 编码优化数据结构 | 存储复杂数据推荐使用 json_encode() |
七、官方与实用链接
小结
| 项目 | 是否推荐 |
|---|---|
| 小流量项目 | ✅ 可用简单方式如上所述 |
| 中大型项目 | ✅ 建议结合队列、缓存预热、分布式锁等 |
| 高并发项目 | ✅ 应加入缓存一致性控制机制(如延迟双删) |
更多详细内容请关注其他相关文章!