缓存是提升 Web 应用性能最直接有效的手段之一。Laravel 提供了一个统一的 API 来操作多种缓存后端,包括 Redis、Memcached、数据库、文件 等。通过合理使用缓存,可以大幅减少数据库查询、外部 API 调用等耗时操作,让应用飞起来。
缓存配置文件位于 config/cache.php。默认驱动可通过 .env 中的 CACHE_STORE 设置(Laravel 11+ 使用 store)。常用驱动如下:
| 驱动 | 说明 | 适用场景 |
|---|---|---|
file | 将缓存存储到 storage/framework/cache 目录 | 开发环境、单机部署 |
database | 使用数据库表存储缓存,需运行 php artisan cache:table | 中小型应用,无 Redis |
redis | 基于 Redis,高性能、支持持久化 | 生产环境首选 |
memcached | 基于 Memcached,极高读写速度 | 对速度要求极高,可接受数据丢失 |
array | 仅当前请求有效的数组缓存,用于测试 | 单元测试 |
配置示例 (.env)
CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
通过 Cache Facade 可以轻松存取数据。所有缓存项都有键(key)和可选的过期时间(秒)。
use Illuminate\Support\Facades\Cache;
// 永久存储(永不过期,但可能被驱逐)
Cache::put('key', 'value');
// 存储并设置过期时间(秒)
Cache::put('key', 'value', 600); // 10分钟
// 如果键不存在则存储,返回布尔值
Cache::add('unique_key', 'value', 60);
// 获取或存储(闭包方式)
$users = Cache::remember('users', 3600, function () {
return DB::table('users')->get();
});
$value = Cache::get('key');
// 如果不存在,返回默认值
$value = Cache::get('key', 'default');
$value = Cache::get('key', function () {
return 'default value';
});
// 检查键是否存在
if (Cache::has('key')) { ... }
// 获取后删除(一次性读取)
$value = Cache::pull('key');
Cache::forget('key'); // 删除单个
Cache::flush(); // 清空整个缓存(谨慎!)
Cache::increment('count');
Cache::increment('count', 5);
Cache::decrement('count', 2);
缓存标签允许你将相关的缓存项分组,然后一次性清除整个组。仅 redis、memcached 和 database 驱动支持标签。
// 存储带标签的缓存
Cache::tags(['people', 'artists'])->put('John', $john, 3600);
Cache::tags(['people', 'authors'])->put('Anne', $anne, 3600);
// 访问带标签的缓存
$john = Cache::tags(['people', 'artists'])->get('John');
// 删除某个标签的所有缓存(不影响其他标签)
Cache::tags(['people'])->flush();
// 或删除多个标签的交集
Cache::tags(['people', 'artists'])->flush();
原子锁用于避免并发操作(例如定时任务重叠、重复扣减库存)。锁通过缓存驱动实现,Redis 驱动天然支持原子性。
use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('processing_order', 10); // 锁名称,过期秒数
if ($lock->get()) {
// 成功获取锁,执行关键操作
// ...
// 释放锁
$lock->release();
} else {
// 无法获取锁,稍后重试
}
// 阻塞直到获取锁(最多等待5秒)
$lock->block(5);
try {
// 操作
} finally {
$lock->release();
}
cache()
Laravel 提供了全局辅助函数 cache() 简化缓存操作:
// 获取
$value = cache('key');
// 存储(如果未提供过期时间,则永久存储)
cache(['key' => 'value'], 600);
// 获取或设置(类似 remember)
$users = cache()->remember('users', 3600, function () {
return User::all();
});
// 删除
cache()->forget('key');
如果需要使用未内置的缓存服务(如 MongoDB),可以扩展缓存系统。在服务提供者中注册:
use Illuminate\Support\Facades\Cache;
Cache::extend('mongo', function ($app) {
return Cache::repository(new MongoStore);
});
remember 或缓存空值避免穿透;为过期时间添加随机偏移量防止雪崩。user:profile:1,便于管理。saved、deleted)触发清理。array 驱动,避免测试互相干扰。
// 在 User 模型中
protected static function booted()
{
static::saved(function () {
Cache::forget('users:all');
Cache::forget('user:' . $this->id);
});
}
缓存系统常与速率限制配合使用,如限制 API 请求次数。Laravel 的 RateLimiter Facade 背后依赖缓存。
use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$userId,
$perMinute = 5,
function () {
// 发送消息逻辑
}
);
if (! $executed) {
return 'Too many messages!';
}
php artisan cache:clear # 清除所有缓存
php artisan cache:table # 生成数据库缓存的迁移文件
php artisan config:cache # 缓存配置文件(生产环境)
php artisan route:cache # 缓存路由
php artisan view:cache # 缓存编译的 Blade 模板
Laravel 的缓存系统提供了统一的 API 和多种驱动,让你可以灵活地将热点数据存储在最快的地方。掌握基础存取、标签、原子锁以及最佳实践,将极大地提升应用性能和稳定性。配合模型事件自动清理缓存,可以保持数据一致性。