在Web应用访问量逐渐增长后,数据库往往会成为第一个性能瓶颈。ThinkPHP框架自带了一套完善的缓存机制,支持File、Redis、Memcache等多种驱动,其中Redis因其丰富的数据结构和极快的读写速度,是生产环境中最常见的选择。本文将从零开始讲解Redis缓存驱动在ThinkPHP中的配置方法与实际使用技巧。

一、Redis缓存驱动的基础配置
ThinkPHP的缓存配置统一放在项目根目录下的config/cache.php文件中。默认情况下框架使用File驱动,要切换到Redis,只需修改default配置项并添加Redis连接参数。下面是一个典型的配置示例:
return [
// 默认缓存驱动改为redis
'default' => env('cache.driver', 'redis'),
// 缓存连接池配置
'stores' => [
'redis' => [
// 驱动类型,必须是Cache驱动而非Session驱动
'type' => 'cache\driver\Redis',
// Redis服务器地址
'host' => '127.0.0.1',
'port' => 6379,
// 如果服务器设置了密码,必须填写
'password' => '',
// 选择数据库编号,Redis默认有16个库
'select' => 0,
// 缓存前缀,多项目共用Redis时建议设置
'prefix' => 'think:',
// 缓存有效期,单位秒,0表示永久有效
'expire' => 3600,
// 序列化方式,推荐_serialize以支持数组和对象
'serialize' => ['think\sess\driver\Redis', 'none'],
],
// 可以保留file驱动作为备用
'file' => [
'type' => 'File',
'path' => '',
'prefix' => '',
'expire' => 0,
],
],
];
</pre>
这里有几个关键点需要注意。首先是type的取值,在ThinkPHP6中使用cache\driver\Redis,部分版本写作Redis,具体以所用版本的官方文档为准。其次是select参数,Redis默认提供0到15共16个数据库,通过编号隔离不同业务的缓存数据,避免键名冲突。最后是prefix配置,当多个项目共用同一个Redis实例时,给每个项目设置不同的前缀是良好的习惯,框架会自动在所有键名前拼接该前缀。
另外,配置完成后务必确认PHP环境已安装redis扩展。可以通过php -m命令查看,或新建一个phpinfo页面检查。如果缺少扩展,在Linux下可以通过pecl install redis安装后重启服务;Windows环境则需要下载对应版本的dll文件并配置到php.ini中。没有这个扩展,即使配置正确也会抛出连接异常。
二、缓存的读写与删除操作
配置完成后,就可以在控制器或模型中使用缓存了。ThinkPHP提供了think\facade\Cache门面类,用法非常简洁:
use think\facade\Cache;
// 写入缓存:键名为user_info_100,有效期为600秒
Cache::store('redis')->set('user_info_100', ['name' => '张三', 'age' => 25], 600);
// 读取缓存,键不存在时返回null
$user = Cache::store('redis')->get('user_info_100');
// 读取缓存,键不存在时返回默认值
$user = Cache::store('redis')->get('user_info_101', []);
// 删除指定键
Cache::store('redis')->delete('user_info_100');
// 缓存不存在时才写入,常用于防止重复写入
Cache::store('redis')->remember('config', function () {
// 该闭包的返回值会被自动缓存
return Db::name('config')->select()->toArray();
}, 3600);
// 清空当前前缀下的所有缓存,慎用
Cache::store('redis')->clear();
在实际项目中,最推荐使用remember方法实现缓存穿透式读取。它的逻辑是先查缓存,命中则直接返回;未命中则执行闭包函数获取数据并自动写入缓存,下次请求就能命中。这种方式把缓存逻辑收敛到一行代码,避免了手写if-else判断的繁琐。
一个常见的应用场景是热点数据缓存,例如首页商品列表、分类导航等。这类数据访问频率极高但更新频率较低,非常适合缓存处理。示例代码如下:
namespace app\controller;
use app\BaseController;
use think\facade\Cache;
use think\facade\Db;
class Index extends BaseController
{
public function goodsList()
{
// 商品列表缓存10分钟,未命中时自动查询数据库
$list = Cache::remember('hot_goods', function () {
return Db::name('goods')
->where('status', 1)
->order('sales', 'desc')
->limit(20)
->select()
->toArray();
}, 600);
return json(['code' => 0, 'data' => $list]);
}
// 后台修改商品后清除缓存
public function updateGoods()
{
// ...更新数据库逻辑...
Cache::delete('hot_goods');
return json(['code' => 0, 'msg' => '更新成功']);
}
}
三、用Redis实现Session共享与会话保持
当项目部署多台服务器并使用Nginx做负载均衡时,如果Session仍存储在各服务器的本地文件中,就会出现用户登录状态丢失的问题——请求被分发到另一台没有该Session的服务器时,用户会被强制下线。解决思路就是把Session统一存到Redis中,所有服务器共享同一份会话数据。
ThinkPHP的Session配置文件位于config/session.php,修改type为Redis并填写连接参数即可:
return [
// 会话驱动改为redis
'type' => 'redis',
'host' => '192.168.1.100',
'port' => 6379,
'password' => 'your_password',
// session使用的数据库编号,建议与缓存分开
'select' => 1,
// 会话有效期,单位秒
'expire' => 3600,
// 键名前缀
'prefix' => 'sess:',
'cookie' => [
'httponly' => true,
'secure' => false,
],
];
配置完成后无需修改任何业务代码,框架会自动将Session读写切换到Redis。建议将Session和缓存分别放在不同的数据库编号中(例如缓存用0号库、Session用1号库),这样排查问题时互不干扰,清理缓存时也不会误删用户会话。如果Redis服务器与Web服务器不在同一台机器上,务必确认Redis的bind配置和防火墙规则允许Web服务器访问,同时一定要设置requirepass密码,避免Redis暴露在公网导致数据泄露甚至被恶意利用。
四、常见问题排查与性能优化建议
实际使用中难免遇到各类问题,下面列出几个高频问题的排查思路。
1. 连接被拒绝(Connection refused):先确认Redis服务是否启动,可用redis-cli ping测试,返回PONG说明服务正常。如果服务正常但仍连不上,检查配置中的host和port是否正确,远程连接还需检查Redis配置文件中的bind 127.0.0.1是否限制了访问IP,以及服务器的安全组或防火墙是否放行了6379端口。
2. 缓存穿透导致数据库压力骤增:当大量请求查询一个不存在的键时,缓存永远无法命中,所有请求都会打到数据库。解决方案是在查询数据库未果时也缓存一个空值(例如缓存空数组,有效期设置短一些如60秒),或者在remember的闭包中对空结果做兜底处理。
3. 连接数过高与超时:高并发场景下每次请求都新建Redis连接会带来额外开销,可以通过persistent配置开启持久连接,减少TCP握手次数。同时在php.ini中合理设置default_socket_timeout,避免网络抖动时请求长时间阻塞。
'redis' => [
'type' => 'cache\driver\Redis',
'host' => '127.0.0.1',
'port' => 6379,
// 开启持久连接,复用TCP链接
'persistent' => true,
'prefix' => 'think:',
'expire' => 3600,
],
4. 缓存与数据库数据不一致:这是分布式系统中的经典难题。通常采用失效策略处理——更新数据库后立即删除相关缓存,让下次请求重新加载。对于一致性要求不高的数据,可以接受短暂的不一致,依靠较短的过期时间自然收敛。切记不要在更新数据库之前删缓存,这个顺序在并发场景下更容易产生脏数据。
总结来看,ThinkPHP集成Redis缓存的成本很低,但要在生产环境稳定运行,需要关注扩展安装、网络连通性、键前缀隔离、Session共享配置以及缓存一致性策略这些细节。把这些环节都处理妥当,Redis就能真正发挥出为数据库减压、提升响应速度的价值。
Redis缓存ThinkPHP配置session共享修改时间:2026-09-02 07:34:35