Yii框架在运行过程中会把缓存文件、日志、调试信息、资源发布副本等大量临时数据写入runtime目录。项目跑得越久,这个目录就越大,动辄占用几个GB甚至几十GB的磁盘空间,严重时直接把磁盘写满,导致数据库连接失败、页面500报错。这篇文章就来详细讲讲runtime目录里到底装了什么,以及如何安全、高效地清理这些缓存文件。

一、runtime目录的构成与缓存生成机制
Yii应用的runtime目录默认位于应用根目录下,其路径可以通过Yii::getAlias('@runtime')获取。框架对这个目录的写入主要来自几个方面:缓存组件写入的缓存数据文件、日志组件按FileTarget方式写入的日志、调试工具栏Debug Module产生的请求分析数据、Gii代码生成器的临时文件,以及资源管理器AssetManager发布的assets副本。
其中增长最快的通常是两块:一是缓存目录runtime/cache,如果项目使用了文件缓存即yii\caching\FileCache,每个缓存键都会落成一个独立的bin文件,缓存键设计不合理时文件数量会暴涨;二是runtime/logs目录,默认按天滚动生成app.log和error.log,如果日志级别配置过宽、请求量又大,一天生成几百MB的日志并不罕见。
理解这些机制很重要,因为不同的文件有不同的清理策略。缓存文件删了会自动重建,日志文件删了历史就没了,assets目录删除后需要在下次请求时重新发布。盲目地一条rm -rf命令全删,虽然不会导致代码损坏,但可能带来短暂的服务抖动。
二、使用Yii自带的机制清理缓存
Yii提供了完善的缓存管理接口,清理缓存首选框架自身的方法,而不是直接删文件。yii\caching\Cache基类提供了flush()方法,可以清空指定缓存组件的全部数据。
// 在控制器或命令行中执行 Yii::$app->cache->flush(); // 如果配置了多个缓存组件,可以分别清理 Yii::$app->cache->flush(); // 主缓存 Yii::$app->sessionCache->flush(); // 会话相关缓存 // 也可以使用静态方法按组件ID清理 \yii\caching\Cache::flushAll();
更推荐的做法是封装一个控制台命令,便于通过命令行或定时任务调用。在commands目录下创建清理命令:
<?php
namespace app\commands;
use yii\console\Controller;
use Yii;
class CacheController extends Controller
{
// 用法:php yii cache/clear
public function actionClear()
{
$components = ['cache', 'cacheRedis'];
foreach ($components as $id) {
if (Yii::$app->has($id)) {
Yii::$app->get($id)->flush();
$this->stdout("缓存组件 {$id} 已清空\n");
}
}
return self::EXIT_CODE_NORMAL;
}
}如果开启了Debug模块,调试数据存放在runtime/debug目录,会随时间持续膨胀。可以在配置中限制保存的条数,DebugModule提供了historySize参数,控制最多保留多少条请求记录,超出后自动删除旧数据,这是从源头上控制体积的好办法。
三、手动与定时清理方案
有些文件框架不会自动回收,必须靠运维手段处理。典型的有日志归档残留、assets副本和临时上传文件。对于这些内容,可以编写一个清理脚本,结合crontab定期执行。
#!/bin/bash # clean_runtime.sh 定期清理runtime目录 RUNTIME=/var/www/myapp/runtime # 删除30天前的日志文件 find $RUNTIME/logs -name "*.log*" -type f -mtime +30 -delete # 删除7天前的调试数据 find $RUNTIME/debug -type f -mtime +7 -delete # 删除已经不存在的资源对应的历史assets目录(需谨慎,建议低峰期执行) find $RUNTIME -maxdepth 1 -type d -name "assets-*" -empty -delete # 清空临时目录 find $RUNTIME/tmp -type f -mtime +1 -delete
然后在crontab中配置定时执行,比如每天凌晨三点运行:
# 编辑 crontab:crontab -e 0 3 * * * /bin/bash /opt/scripts/clean_runtime.sh >> /var/log/clean_runtime.log 2>&1
日志这块其实有更优雅的方案。Yii的FileTarget支持logVars和maxFileSize、maxLogFiles参数,可以配置单个日志文件超过多大时自动轮转、最多保留几个轮转文件。把这两个参数配上,日志目录基本可以做到自平衡,不需要额外脚本干预。
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
'logFile' => '@runtime/logs/app.log',
'maxFileSize' => 10240, // 单文件最大10MB
'maxLogFiles' => 20, // 最多保留20个轮转文件
'logVars' => [], // 不记录超全局变量,减小体积
],
],
],
],四、运维注意事项与最佳实践
清理缓存文件时有几个容易踩的坑需要提醒。第一是目录权限问题,runtime目录必须保证Web进程用户可写,如果用了sudo执行清理脚本,删出来的空目录属主可能变成root,导致后续框架写入失败,出现莫名其妙的报错。建议脚本中清理后执行chown -R www-data:www-data runtime之类的命令修正属主。
第二是不要在业务高峰期清空全量缓存。文件缓存或Redis缓存一旦flush,大量请求会同时打到数据库重建缓存,形成缓存雪崩。稳妥的做法是分批清理,或者在低峰期操作,清理前先确认数据库能扛住突增的读压力。
第三是建议建立磁盘监控告警。可以使用简单的监控脚本,当runtime所在分区使用率超过80%时发出告警,把问题消灭在磁盘写满之前。同时每年至少检查一次缓存键的设计,避免出现带时间戳的动态键无限增长的场景,从源头减少缓存文件数量。
总结一下:优先使用flush()等框架方法清缓存,日志靠maxFileSize自动轮转,历史文件交给crontab定期清理,再加上权限检查和磁盘告警,runtime目录就能长期保持在一个健康的体积范围内。
Yii缓存清理Runtime目录维护Yii框架运维修改时间:2026-09-15 12:46:32