Laravel什么时候清除缓存?

8

我正在尝试使用 Laravel 5 来与 Redis 配合使用,以缓存查询/结果来使我的应用程序运行更快。

然而,我有几个问题,这些问题应该能够帮助我决定什么时候使用 Cache 是合适的,什么时候不是。

假设我有以下内容:

$interview= Cache::remember('SomeUniqueKey', 180, function(){

    return SurveyInterview::where('user_id', 123)
                          ->with([
                                    'current_step.page',
                                    'pages'
                                ])
                          ->first();
});

前面的代码应该缓存 Eloquent 返回的集合组合,总共包括 3 个查询。第一个查询是查询模型,第二个查询是查询 current_step.page 关系,最后一个查询是查询 pages 关系。
据我理解,只要我多次执行上述代码,Laravel 就会返回缓存中的集合,直到从缓存集合的时间算起已经过了 180 分钟。
问题是,如果我的数据库表发生更新,Laravel 会自动删除缓存吗?换句话说,当我更新 SurveyInterview 模型时,它会自动删除缓存,还是每次更新模型时都必须手动删除呢?
2个回答

18
这个问题的答案实际上取决于使用的缓存驱动程序。
对于像Memcache或APC这样的驱动程序,这些服务知道如何自我“垃圾回收”并自动清除过期条目。
对于文件驱动程序,它依赖于文件创建的UNIX时间戳来确定是否已过期。在尝试检索它并确定其已过期之前,文件不会被删除。
对于数据库驱动程序,它存储一个过期列并可以从该时间戳确定是否已过期。记录在过期时不会自动删除 - 只有在尝试获取缓存条目并发现它已过期时才会删除(类似于文件驱动程序)。
为了回答总体问题,你是正确的,remember()将继续从缓存中检索它直到它过期。它通过在特定存储类上调用get()方法来实现,对于文件和数据库,如果过期,则会自动刷新条目。当由于过期而返回没有条目时,您的闭包逻辑将执行以生成一组新数据。
据我所知,当更新发生时,它不会清除缓存。在 Illuminate\Database 文件夹中快速搜索 forgetflush 并没有表明它会这样做。话虽如此,您可以使用 model events 检测更新的发生,并通过将类似以下内容添加到模型中轻松地清除缓存。请注意,保留 HTML 标签。
public static function boot()
{
    SurveyInterview::updated(function ($survey) {
        app('cache')->forget('my-survey-key-' . $survey->id);
    });
}

参考文献

FileStore: https://github.com/laravel/framework/blob/5.2/src/Illuminate/Cache/FileStore.php

数据库存储:https://github.com/laravel/framework/blob/5.2/src/Illuminate/Cache/DatabaseStore.php#L66

编辑

Redis、Memcache 和 APC 都可以自行处理刷新。例如,看这个:


关于我正在使用的 Redis,您有什么建议吗?此外,当我使用 Eloquent 更新记录时,它会刷新缓存吗?还是说这是我需要手动执行的操作? - Jaylen
@Jaylen 我添加了一些关于Redis的更多细节。 - Jeremy Harris

4

您需要手动清除缓存。

在您的例子中,不必使用SomeUniqueKey,可以使用survey_userid这样的引用。

现在,您可以向您的模型添加以下事件,在相关数据更新时清除缓存。

public static function boot()
{
    parent::boot();

    static::updated(function($survey)
    {
        Cache::forget('survey_'. $survey->user()->id);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接