Laravel 缓存系统操作

缓存是提升 Web 应用性能最直接有效的手段之一。Laravel 提供了一个统一的 API 来操作多种缓存后端,包括 Redis、Memcached、数据库、文件 等。通过合理使用缓存,可以大幅减少数据库查询、外部 API 调用等耗时操作,让应用飞起来。

⚡ 核心价值: 将频繁访问但不常变化的数据(如用户信息、配置项、热点列表)存入高速缓存中,下次请求直接从缓存读取,避免重复计算或查询。

1. 缓存配置与驱动

缓存配置文件位于 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
                    

2. 基本缓存操作

通过 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);
                    

3. 缓存标签

缓存标签允许你将相关的缓存项分组,然后一次性清除整个组。仅 redismemcacheddatabase 驱动支持标签。


// 存储带标签的缓存
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();
                    

4. 缓存原子锁

原子锁用于避免并发操作(例如定时任务重叠、重复扣减库存)。锁通过缓存驱动实现,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();
}
                    

5. 辅助函数 cache()

Laravel 提供了全局辅助函数 cache() 简化缓存操作:


// 获取
$value = cache('key');

// 存储(如果未提供过期时间,则永久存储)
cache(['key' => 'value'], 600);

// 获取或设置(类似 remember)
$users = cache()->remember('users', 3600, function () {
    return User::all();
});

// 删除
cache()->forget('key');
                    

6. 自定义缓存驱动

如果需要使用未内置的缓存服务(如 MongoDB),可以扩展缓存系统。在服务提供者中注册:


use Illuminate\Support\Facades\Cache;

Cache::extend('mongo', function ($app) {
    return Cache::repository(new MongoStore);
});
                    

7. 最佳实践与常见陷阱

  • 合理设置过期时间: 不要永久缓存易变数据,根据业务更新频率设置 TTL(Time To Live)。
  • 缓存穿透/雪崩: 使用 remember 或缓存空值避免穿透;为过期时间添加随机偏移量防止雪崩。
  • 序列化注意: 缓存闭包或复杂对象时确保其可序列化,推荐缓存简单数组或 DTO。
  • 命名规范: 使用冒号分隔命名空间,例如 user:profile:1,便于管理。
  • 缓存与数据库一致性: 当数据更新时,及时删除或更新相关缓存,可使用模型事件(saveddeleted)触发清理。
  • 测试环境: 使用 array 驱动,避免测试互相干扰。

示例:模型事件自动清理缓存


// 在 User 模型中
protected static function booted()
{
    static::saved(function () {
        Cache::forget('users:all');
        Cache::forget('user:' . $this->id);
    });
}
                    

8. 缓存与速率限制

缓存系统常与速率限制配合使用,如限制 API 请求次数。Laravel 的 RateLimiter Facade 背后依赖缓存。


use Illuminate\Support\Facades\RateLimiter;

$executed = RateLimiter::attempt(
    'send-message:'.$userId,
    $perMinute = 5,
    function () {
        // 发送消息逻辑
    }
);

if (! $executed) {
    return 'Too many messages!';
}
                    

9. 缓存相关 Artisan 命令


php artisan cache:clear      # 清除所有缓存
php artisan cache:table      # 生成数据库缓存的迁移文件
php artisan config:cache     # 缓存配置文件(生产环境)
php artisan route:cache      # 缓存路由
php artisan view:cache       # 缓存编译的 Blade 模板
                    

10. 总结

Laravel 的缓存系统提供了统一的 API 和多种驱动,让你可以灵活地将热点数据存储在最快的地方。掌握基础存取、标签、原子锁以及最佳实践,将极大地提升应用性能和稳定性。配合模型事件自动清理缓存,可以保持数据一致性。

📖 官方文档: Laravel Cache 提供了更深入的配置和高级用法。