olegkravec/expirable

具有真正过期功能的 Laravel 模型缓存 :)

1.3.1 2020-05-22 10:12 UTC

This package is auto-updated.

Last update: 2024-09-22 19:26:46 UTC


README

历史背景

在开发注重高性能的项目时,我开始深入研究缓存库的实现,因为我发现使用现有库在 Redis 中产生了许多不必要的缓存请求。例如,研究了 watson/rememberablegenealabs/laravel-model-caching 后发现,每个请求除了数据外,还有许多其他键,如 ...-cooldown:saved-at, ...:invalidated-at, ...:seconds, ...:saved-at, ...:invalidated-at, ...:seconds。这些数据用于缓存失效,但为服务器 PHP 创建了过多的操作,并且这不仅是数据,数据不是以键值对(SET-GET)的形式存储,而是在中间缓冲区(SADD,SMEMBERS)中存储,这会消耗额外的内存并导致对 Redis 进行大量查询,比较时间戳以及删除过期的数据。

我的目标是创建一个系统,它能够最大限度地减少额外的负载,通过使用 Redis 的所有功能,我实现了这一点。

用法

安装

该库可在 composer 仓库中找到: composer require olegkravec/expirable

启用缓存

为了方便使用,我默认在您将特性添加到模型后启用缓存 use Expirable;

<?php
namespace App;

use OlegKravec\Expirable\Expirable;
use Illuminate\Database\Eloquent\Model;

class YourModel extends Model
{
    use Expirable;
    
    /**
    * Your code here...
    */
}

连接后,所有数据将自动缓存 300 秒(5 分钟)

额外设置

目前,为整个数据模型提供了以下预置配置

  • 所有与该模型关联的缓存数据的生存时间
  • 自定义数据键的前缀
  • 启用按 md5 算法对缓存键进行哈希处理,可以最小程度地减少键的长度约 120 字节,但会增加哈希处理带来的额外负载。
<?php
class YourModel extends Model
{
    use Expirable;
    
    public $_expirable_ttl = 100; 
    public $_expirable_prefix = "MyModelPrefix";
    public $_expirable_cache_hashing_enabled = true;
    
    /**
    * Your code here...
    */
}

禁用缓存

如果您不需要从缓存中获取某个请求的数据,可以调用 disableCache() 方法

User::where("key","value")->disableCache()->get()

更改 TTL

由于默认情况下缓存将保存数据 5 分钟,您可以通过 expire(int $seconds) 设置自己的时间限制

User::where("key","value")->expire(10)->get()

在这种情况下,获取的数据将被缓存 10 秒。

更新 TTL

有时,只有在数据被访问时才更新数据的生存时间会更好。这将显著减少对数据库的选择次数,并通过仅缓存真正受欢迎的数据来减少不必要内存的占用。为此,请调用 resetExpire(int $seconds)

User::where("key","value")->resetExpire(10)->get()

如果数据已在缓存中,其生存时间将再次设置为指定的秒数;如果数据不在缓存中,则将获取并保存 10 秒。

键的哈希处理

当需要执行大量查询时,我强烈建议使用键的哈希处理,这可以大大减少内存消耗,但会增加负载 - hashExpirable()

User::where("key","value")->where("key2","value2")->where("key3","value3")->where("key4","value4")->take(10)->skip(5)->hashExpirable()->get()

如示例所示,任何长度的键都将转换为 32 个字符的字符串。查询数据库的样本越多,节省就越多!

自定义前缀

因为数据键看起来大约是这样的

expirable:${tableName}:${yourPrefix}:[{"type":"Basic","column":"id","operator":">","value":2,"boolean":"and"}]:null:{"select":[],"from":[],"join":[],"where":[2],"having":[],"order":[],"union":[]}

您不能使用单个键保存不同的数据,但如果您需要这样做,则对于每个请求,请通过 prefix(string $cachePrefix) 指定自己的前缀。

User::where("key","value")->prefix("yourPrefix")->get()