跳转到正文

缓存

Queuety 包含一个缓存层,可减少队列暂停检查、速率限制计数器、工作流状态查询和锁操作等热点路径上的数据库查询。调用 Queuety::init() 时会自动初始化缓存。

缓存接口

所有缓存后端都实现 Queuety\Contracts\Cache:

方法 返回值 说明
get( string $key ) mixed 获取一个值。如果未找到或已过期,则返回 null。
set( string $key, mixed $value, int $ttl = 0 ) void 存储一个值。TTL 为 0 表示永不过期。
delete( string $key ) void 移除一个值。
has( string $key ) bool 检查键是否存在且尚未过期。
add( string $key, mixed $value, int $ttl = 0 ) bool 仅当键不存在时才设置值(原子操作)。设置成功时返回 true。
flush() void 移除缓存中的所有项目。ApcuCache::flush() 会调用 apcu_clear_cache(),清除服务器上的所有 APCu 条目,而不只是 Queuety 的条目。

内置后端

MemoryCache(默认)

Queuety\Cache\MemoryCache 是基于数组、按进程隔离的缓存。项目存储在 PHP 数组中,并会在进程退出时丢失。APCu 不可用时,这是默认后端。

它无需扩展,适用于单工作进程部署,并使每个工作进程彼此隔离。

ApcuCache

Queuety\Cache\ApcuCache 使用 APCu 扩展,在同一服务器上的所有 PHP 进程间共享内存。所有键都会自动添加前缀 queuety:,以避免与其他应用发生冲突。

此后端需要 php-apcu 扩展,可在同一服务器的工作进程间共享缓存条目,并通过 apcu_add() 实现真正的原子操作 add()。

自动检测

Queuety\Cache\CacheFactory 会自动选择可用的最佳后端:

如果存在 apcu_store(),且 apcu_enabled() 返回 true,Queuety 就会使用 ApcuCache。否则会回退到 MemoryCache。此操作在 Queuety::init() 中进行,因此默认行为无需额外配置。

缓存内容

以下多个子系统会在内部使用缓存层:

数据 用途
队列暂停状态 避免工作进程每次循环迭代都查询数据库
速率限制计数器 在内存中跟踪执行次数,而不是查询数据库
工作流状态 减少多步骤工作流推进期间的读取次数
锁状态 加快唯一任务和互斥锁中间件的锁存在性检查

TTL 配置

默认缓存 TTL 为 5 秒,适用于队列暂停状态和速率限制计数器;工作流状态和状态读取会缓存固定的 2 秒,该时长不会因常量而改变。你可以在 wp-config.php 中使用 QUEUETY_CACHE_TTL 常量覆盖默认值:

PHP
define( 'QUEUETY_CACHE_TTL', 10 ); // 10 seconds

较短的 TTL 意味着更频繁地查询数据库,但数据更新鲜。较长的 TTL 会降低数据库负载,但会导致数据更陈旧。对大多数部署而言,默认的 5 秒是一个不错的平衡。

自定义缓存后端

要使用自定义缓存后端(Redis、Memcached 或其他后端),请实现 Contracts\Cache 接口,并在 Queuety::init() 之前调用 Queuety::set_cache():

PHP
use Queuety\Contracts\Cache;
use Queuety\Queuety;

class RedisCache implements Cache {
    public function get( string $key ): mixed { /* ... */ }
    public function set( string $key, mixed $value, int $ttl = 0 ): void { /* ... */ }
    public function delete( string $key ): void { /* ... */ }
    public function has( string $key ): bool { /* ... */ }
    public function add( string $key, mixed $value, int $ttl = 0 ): bool { /* ... */ }
    public function flush(): void { /* ... */ }
}

// Set the cache before init() so all subsystems use it.
Queuety::set_cache( new RedisCache() );
Queuety::init( $connection );

如果在 init() 之前调用 set_cache(),则会完全跳过工厂自动检测,并使用你的自定义后端。

访问缓存

随时获取当前启用的缓存实例:

PHP
$cache = Queuety::cache();

$cache->set( 'my_key', 'my_value', 60 );
$value = $cache->get( 'my_key' );

这会返回当前启用的后端(MemoryCache、ApcuCache 或你的自定义实现)。