PHP用Redis存会话和缓存的核心是将文件或数据库存储替换为内存操作,需正确配置session.save_handler=redis与save_path、禁用PHP垃圾回收,并分库隔离会话(database=1)与业务缓存(如database=2),同时规范键名、TTL及防雪崩/击穿策略。

PHP平台用Redis存会话和缓存,核心是把原本写在文件或数据库里的数据,换成更快、更可控的内存操作。关键不在“能不能”,而在“怎么配对、怎么用稳”。
配置Redis会话存储(让登录态不丢)
默认PHP会话存在本地文件,多台服务器时用户可能刚登录就登出。改用Redis后,所有节点共享同一份session数据。
- 修改php.ini(推荐):
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?database=1"
若Redis有密码,加上
&auth=your_pass;database=1建议显式指定,避免和缓存数据混用 - 重启PHP服务(如
sudo systemctl restart php8.2-fpm),否则配置不生效 - 必须禁用PHP自带垃圾回收:session.gc_maxlifetime = 0,否则PHP会随机扫描Redis删key,导致用户莫名掉线
- 验证是否成功:用
redis-cli连上后执行KEYS PHPREDIS_SESSION*,能看到带session ID的key即为生效
代码中手动存取缓存(灵活控制数据生命周期)
不是所有数据都适合放session里,比如用户资料、API响应、热门列表等,更适合用setex或set主动管理。
- 基础写法示例:
$redis = new Redis();<br>$redis->connect('127.0.0.1', 6379);<br>// 缓存用户信息,3600秒后自动过期<br>$redis->setex('user:1001', 3600, json_encode(['name' => '张三', 'role' => 'admin']));<br>// 读取时先查缓存,命中则返回,不命中再查库并回填<br>$cached = $redis->get('user:1001');<br>if ($cached) {<br> return json_decode($cached, true);<br>} else {<br> $data = fetchFromDb(1001);<br> $redis->setex('user:1001', 3600, json_encode($data));<br> return $data;<br>}立即学习“PHP免费学习笔记(深入)”;
- 键名建议带业务前缀(如
user:、api:),方便清理和监控 - 过期时间别全设成固定值,高频变动数据用短TTL(如60秒),静态配置可用长TTL(如24小时)甚至永不过期(配合主动更新)
避开几个典型坑
配置对了不等于就稳了,这些细节常被忽略:
-
缓存命中率低于60%:说明很多请求没走缓存。检查键名是否一致(大小写、空格、URL参数顺序)、是否误用了
set没设过期、或缓存逻辑被绕过 -
Redis内存爆满:用
INFO memory看used_memory,设置maxmemory和淘汰策略(如maxmemory-policy allkeys-lru) -
缓存雪崩:大量key在同一时间过期,引发数据库瞬间压力。解决办法是给TTL加随机偏移(如
3600 + rand(0, 600)) -
缓存击穿:某个热点key失效瞬间,大量请求穿透到数据库。可用互斥锁(如
SET key value EX 30 NX)保护重建逻辑
会话与缓存的数据物理隔离
虽然都用Redis,但session和业务缓存最好分库存储:
- 会话用
database=1,缓存用database=2或更高,避免FLUSHDB误清session - 若Redis版本≥6且启用了ACL,可为session和缓存分别创建不同权限的用户,进一步隔离风险
- 用不同key前缀也能辅助区分,比如session默认前缀是
PHPREDIS_SESSION:,业务缓存统一用cache:或app:



















