用 info memory 命令可直接获取 Redis 实际内存占用,其中 used_memory 是核心指标(单位字节),需结合 maxmemory 设置分级告警,避免依赖 ThinkPHP Cache 封装层。

用 info memory 直接查 Redis 实际内存占用
ThinkPHP 本身不提供 Redis 内存监控能力,它只是封装了连接和读写操作;真正要看内存,得绕过框架直接跟 Redis 通信。最可靠、零依赖的方式就是调用 Redis 原生命令 INFO memory —— 它返回的是服务端实时的内存快照,不受 PHP 进程或 ThinkPHP 缓存层干扰。
- 必须用原生
Redis实例(非 ThinkPHP 的Cache::),否则拿不到底层连接:$redis = new \Redis(); $redis->connect(config('cache.stores.redis.host'), config('cache.stores.redis.port')); $memoryInfo = $redis->info('memory'); -
used_memory是核心指标:单位字节,代表 Redis 已分配给数据的内存(不含碎片、不含 RSS);别误用used_memory_rss,它含系统级开销,波动大,不适合做阈值告警基准 - 如果
mem_fragmentation_ratio> 1.5,说明内存碎片严重,used_memory看似不高但实际可能触发 OOM;此时used_memory和used_memory_rss差值会很大
在 ThinkPHP 中安全嵌入内存采集逻辑
不能把 info memory 放到高频接口里——它虽快,但频繁调用会增加 Redis 主线程负担,尤其在高并发下可能拖慢其他命令。合理做法是把它抽成低频后台任务,或只在运维入口(如 admin 页面)按需触发。
- 推荐用 ThinkPHP 的命令行指令(
php think redis:monitor)封装采集逻辑,避免污染 Web 请求生命周期 - 配置中密码字段必须显式传入,否则
connect()会失败且无明确报错:$redis->auth(config('cache.stores.redis.password')); - 务必设置超时:
$redis->setOption(\Redis::OPT_READ_TIMEOUT, 0.5);,防止 Redis 响应卡住整个 PHP 进程 - 不要用
predis/predis替代原生Redis扩展——Predis 的info()返回结构不一致,info('memory')可能返回空数组或抛异常
设置内存溢出预警的实用阈值策略
单纯看 used_memory 绝对值意义不大,关键是要结合 Redis 配置的 maxmemory 做比例判断。很多团队设 80% 告警,结果发现根本来不及处理——因为从 80% 到触发 LRU 淘汰甚至 OOM,可能就几秒。
- 建议分两级告警:
• 70%:发邮件/钉钉提醒,人工检查是否有异常 key 或突发写入
• 85%:自动触发redis-cli --bigkeys扫描(需另起进程,不阻塞主逻辑),并记录 top5 大 key 到日志 - 注意 Linux 内核的 OOM Killer 行为:若没配 swap,
used_memory_rss接近物理内存时,Redis 进程会被直接 kill,不会等你告警 - ThinkPHP 日志里记内存数据时,别只存数字,要带上时间戳和
mem_fragmentation_ratio:Log::info("redis_mem: {$memoryInfo['used_memory']}B, frag: {$memoryInfo['mem_fragmentation_ratio']}");
为什么 Cache::get('xxx') 查不到内存问题
因为 ThinkPHP 的 Cache 类只负责键值存取,它完全不知道 Redis 整体内存水位。你用 Cache::set() 写入 10 万个 key,Cache 不会告诉你内存快满了——它只管成功与否。所有“缓存击穿”“雪崩”类问题,根源都在 Redis 服务层,不在框架封装层。
- 常见错误:在控制器里写
if (Cache::has('config')) { ... }就以为监控到位了——这只是验证连通性,和内存无关 - 更隐蔽的坑:用了
select切库,但info memory默认统计的是当前数据库(db0),如果业务分散在多个 db,得先$redis->select(1)再 info,否则数据不准 - 生产环境禁用
debug模式下的自动内存 dump,ThinkPHP 开启调试模式时某些插件会偷偷调DEBUG OBJECT,这命令在大数据量 key 上会阻塞 Redis 几秒
真实线上出问题时,90% 的“内存溢出”不是因为数据太多,而是 key 没设过期、hash 字段无限膨胀、或者用 string 存了本该用 zset 的有序集合。这些都得靠 redis-cli --bigkeys 和 memory usage xxx 逐个确认,没有捷径。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











