PHP Redis未利用内存缓存致查询变慢,该如何处理?
问题解答
首先纠正你的核心误解:Redis本身是运行在独立服务器(或本地)的远程内存数据库,PHP的Redis客户端每次调用$redis->get()都会发起网络请求去Redis服务器读取数据,它不会自动在当前PHP进程的内存里缓存结果。所以你看到两次GET请求是完全正常的现象——Redis服务器端确实把数据存在内存里,但客户端(你的PHP代码)每次要拿数据都得发请求过去。
为什么页面加载变慢?
你用Redis后反而变慢,大概率是这几个原因:
- 如果用的是redis.io云服务,网络延迟比本地MySQL高(比如跨地域的云节点),单次Redis请求的耗时反而超过直接查MySQL;
- 你的代码每次请求都新建Redis连接(
connect()是短连接),连接建立的开销叠加后拖慢了速度; - 没有做批量查询,高频小请求的网络开销累积起来导致变慢。
怎么解决?
如果需要本地进程内缓存:
是的,你需要自己实现本地缓存逻辑,或者用现成的工具:- 简单场景可以用PHP静态变量存当前进程内的缓存(比如写个单例辅助类,先查本地静态数组,再查Redis);
- 进阶点可以用APCu扩展(PHP的本地内存缓存扩展,专门存进程内的缓存数据);
- 框架层面的话,比如Laravel/Symfony的Cache组件都支持「分层缓存」——先查本地缓存,再查Redis,最后查DB。
优化Redis的使用方式:
- 改用长连接:把
connect()换成pconnect(),复用Redis连接,避免每次请求新建连接的开销; - 批量获取数据:用
$redis->mget(['key1', 'key2'])一次性获取多个key,减少网络请求次数; - 检查云Redis的网络延迟:如果是跨地域使用,换成和你的应用服务器同区域的Redis节点;
- 合理设置缓存过期时间:避免缓存雪崩,同时确保数据不会太旧。
- 改用长连接:把
补充你的测试代码和日志(格式化后)
测试代码:
$redis = new \Redis(); $redis->connect($_ENV['REDIS_HOST'], $_ENV['REDIS_PORT']); if (isset($_ENV['REDIS_PASSWORD'])) { $redis->auth($_ENV['REDIS_PASSWORD']); } $redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP); $redis->set('test', 'test'); echo $redis->get('test'); echo $redis->get('test');
RedisInsight日志:
13:28:50.583 [0 127.0.0.1:54623] "SET" "1rel:site5:test" "s:4:"test";" 13:28:50.583 [0 127.0.0.1:54623] "GET" "1rel:site5:test" 13:28:50.583 [0 127.0.0.1:54623] "GET" "1rel:site5:test"
内容的提问来源于stack exchange,提问作者Aprilsnar
相关产品推荐
相关产品推荐

