olegkravec / expirable
具有真正过期功能的 Laravel 模型缓存 :)
Requires
- php: >=5.4.0
- illuminate/database: ^5.0|^6.0|^7.0
- predis/predis: ^1.1
This package is auto-updated.
Last update: 2024-09-22 19:26:46 UTC
README
历史背景
在开发注重高性能的项目时,我开始深入研究缓存库的实现,因为我发现使用现有库在 Redis 中产生了许多不必要的缓存请求。例如,研究了 watson/rememberable 和 genealabs/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()