
先把环境搭对:ThinkPHP5+Redis的基础准备
首先得确保你的PHP装了redis扩展——这是基础中的基础,没装的话后面根本用不了。怎么看有没有装?很简单,写个phpinfo()文件运行一下,搜“redis”,有结果就是装了;或者用命令行输php -m
,看看列表里有没有redis。我朋友当时就是没装这个扩展,调了半小时才发现问题,后来用pecl install redis
装了扩展,重启PHP就好了(注意Windows系统可能要手动下载dll文件,放到ext目录里,再改php.ini加extension=redis
)。
接下来改ThinkPHP5的缓存配置文件——在项目根目录的config文件夹里,找cache.php。打开后你会看到默认的type是file(文件缓存),我们要改成redis。具体改这些地方:
我把常用配置项整理成了表格,你对照着改就行:
配置项 | 默认值 | 说明 |
---|---|---|
type | file | 缓存驱动类型,改为redis |
host | 127.0.0.1 | Redis服务器地址 |
port | 6379 | Redis端口 |
password | ” | Redis密码,无则留空 |
改完保存,重启一下项目(比如用php think run
的话,关掉重新开)。这时候ThinkPHP5的缓存驱动就换成Redis了——是不是很简单?
上手实操:ThinkPHP5里Redis缓存的核心操作
接下来就是具体用Redis缓存数据了——ThinkPHP5的Cache类封装得很友好,不用写复杂的Redis命令,直接调用方法就行。我帮朋友调的时候,就是用这几个方法解决了性能问题。
设置缓存的方法是Cache::set()
,参数有三个:键名、值、过期时间(秒)。比如你要存用户ID为1的信息,可以写成这样:
use thinkCache; // 记得先引入Cache类
// 从数据库查用户信息
$userInfo = Db::name('user')->where('id', 1)->find();
// 存到Redis,过期时间1小时(3600秒)
Cache::set('user:info:1', $userInfo, 3600);
这里要注意三点:
user:info:1
),这样后面找起来方便,也不容易和其他缓存冲突——我朋友之前键名乱七八糟,后来改了结构,管理缓存轻松多了; 读取缓存更简单,用Cache::get()
方法,参数是键名。但这里有个关键逻辑:先查缓存,有就用缓存的数据,没有再查数据库,查完再存缓存——这样才能减少数据库压力。比如取刚才存的用户信息:
$userInfo = Cache::get('user:info:1');
if (!$userInfo) {
// 缓存没取到,查数据库
$userInfo = Db::name('user')->where('id', 1)->find();
// 再存到缓存里
Cache::set('user:info:1', $userInfo, 3600);
}
// 用$userInfo做后续操作
我朋友的商品列表页就是这么改的——之前每次都查数据库,现在只有第一次查数据库,后面都用缓存,速度快了好几倍。你可以试试把常用的列表数据(比如文章列表、商品列表)这么处理,效果立竿见影。
当数据更新的时候,一定要记得删对应的缓存——不然读取的还是旧数据。比如用户ID为1的信息改了,就要删user:info:1
这个键:
// 修改用户信息
Db::name('user')->where('id', 1)->update(['name' => '新名字']);
// 删除对应的缓存
Cache::rm('user:info:1');
如果要清所有缓存,可以用Cache::clear()
,但一定要谨慎——这会删掉所有缓存,除非你想重置所有数据,不然别乱点。我朋友之前改商品价格的时候,忘了删缓存,结果用户看到的还是旧价格,后来赶紧加了删除缓存的代码,才解决问题。
几个避坑小技巧
最后再分享几个我实操中 的避坑技巧:
Cache::set('user:info:999', null, 60)
,这样下次再查这个ID,直接取缓存的空值,不用查数据库; 你要是按这些步骤试了,不管成没成,都可以回来留个言——比如遇到扩展装不上的问题,或者缓存没生效,我帮你看看问题出在哪!我朋友当时就是一步步跟着做的,现在他的项目性能比之前好多了,用户反馈也变好了。赶紧去试试吧!
我之前帮朋友处理过一个超常见的bug——用户在后台改了昵称,刷新个人页面还是旧名字,翻来覆去查数据库,数据明明是新的,最后才反应过来:缓存没同步更新!其实解决缓存和数据库不一致的问题,最“笨”但最有效的办法就是:更新数据库的 立刻删掉对应的缓存。比如你用Db::name('user')->where('id',1)->update(['nickname'=>'新名字'])
改了用户信息,下一行一定要加Cache::rm('user:info:1')
——把这个用户的缓存键直接删掉。这样下次有人再查这个用户的信息时,缓存里是空的,自然会去数据库取最新数据,再重新存一份新的缓存,两边就对上了。我朋友当时照做之后,这个bug再也没出现过,他还拍着大腿说:“原来这么简单,之前怎么没想到!”
要是这么做了还偶尔碰到不一致的情况,那我 你调整一下操作顺序:先删缓存,再更新数据库。比如之前做电商项目时,商品价格改了但缓存没清,用户看到旧价格投诉不断,后来我们把逻辑改成“先删缓存键goods:price:1001
,再去改数据库里的价格”。这么做的好处是,就算删完缓存之后、改数据库之前有请求过来(比如0.1秒内的并发),最多也就是直接查一次数据库(因为缓存已经没了),不会读到旧数据;但如果反过来“先改数据库再删缓存”,万一删缓存的时候出问题(比如Redis连接超时、服务器突然断电),那缓存里的旧数据就会一直留在那,后续所有请求都读旧的,问题就彻底炸了。我当时跟开发同学说:“宁肯多查一次数据库,也别让用户看到旧数据——查数据库最多慢一点,看到旧数据可是直接丢用户信任!”
还有人问过我:“删缓存会不会影响性能啊?”其实完全不用担心——Redis的DEL
命令(也就是ThinkPHP里的Cache::rm()
)执行速度快到可以忽略不计,单条命令的执行时间通常连1毫秒都不到,比起数据库查询(比如查一条用户信息要50毫秒),这点开销根本不算什么。与其纠结这点“无所谓的性能”,不如先把“数据一致性”搞定——毕竟用户发一条“我的昵称怎么改不了?”的投诉,可比这点性能损耗麻烦100倍。
我还有个小习惯:给缓存键加“业务前缀”,比如user:info:1
(用户信息)、goods:price:1001
(商品价格),这样删缓存的时候不会误删其他数据,也能快速定位问题。比如之前有个同事把缓存键写成info1
,结果删的时候不小心删掉了info10
的缓存,搞出一堆乱子——加个前缀就能避免这种低级错误。
其实 下来就两句话:改数据必删缓存,删缓存要在改数据前面。别嫌麻烦,这两步做好了,90%的缓存一致性问题都能解决——毕竟缓存的本质是“帮数据库减负”,要是因为缓存搞出数据不一致,那可就本末倒置了。
配置好Redis缓存后,为什么数据没存进去?
首先检查PHP的Redis扩展是否安装成功(用phpinfo()或php -m确认);其次看cache.php配置是否正确——type是不是’redis’、host/port有没有填错(本地默认127.0.0.1:6379)、密码有没有和Redis服务一致;最后确认Redis服务是否启动(Windows用redis-server.exe,Linux用systemctl start redis)。如果以上都对,再检查代码里有没有引⽤Cache类(use thinkCache;),或者键名是不是重复了。
Windows系统下怎么安装PHP的Redis扩展?
先查自己的PHP版本(用php -v看,比如PHP 7.4.3),然后去PECL Redis页面下载对应版本的dll文件(注意“Thread Safe”版对应有ts的PHP);把dll文件放到PHP安装目录的ext文件夹里;打开php.ini,加一行“extension=redis”;重启PHP服务(比如重启Apache或Nginx);最后用phpinfo()检查有没有“redis”项,有就是成功了。
Redis缓存的过期时间设多久合适?
没有固定值,要根据业务场景调整:高频更新的数据(比如商品库存、实时榜单) 设10-60分钟,避免缓存旧数据;中低频数据(比如用户基础信息、文章内容)可以设1-6小时;几乎不更新的数据(比如地区列表、配置参数)设24小时以上也没问题。如果是促销活动、秒杀场景, 把过期时间缩短到5-15分钟,确保用户看到最新的活动信息。
缓存数据和数据库不一致怎么办?
核心解决方法是“更新数据库时同步删除缓存”——比如修改用户信息后,立即用Cache::rm()删掉对应的缓存键(比如user:info:1)。如果还是出现不一致,试试“先删缓存再更新数据库”的逻辑:先删掉旧缓存,再改数据库,这样后续请求会重新查数据库并生成新缓存。 避免“先更新数据库再删缓存”,因为如果删缓存失败,会导致旧缓存一直存在。
Redis提示端口被占用,启动不了怎么办?
首先用命令查6379端口被哪个进程占用:Windows打开 cmd 输“netstat -ano | findstr 6379”,看最后一列的PID;然后打开任务管理器,找对应PID的进程(比如redis-server.exe或其他程序),结束进程;如果不想杀进程,可以改Redis的端口——打开Redis安装目录的redis.conf文件,找到“port 6379”改成其他未占用的端口(比如6380),再启动Redis服务。