缓存
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 常量覆盖默认值:
define( 'QUEUETY_CACHE_TTL', 10 ); // 10 seconds
较短的 TTL 意味着更频繁地查询数据库,但数据更新鲜。较长的 TTL 会降低数据库负载,但会导致数据更陈旧。对大多数部署而言,默认的 5 秒是一个不错的平衡。
自定义缓存后端
要使用自定义缓存后端(Redis、Memcached 或其他后端),请实现 Contracts\Cache 接口,并在 Queuety::init() 之前调用 Queuety::set_cache():
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(),则会完全跳过工厂自动检测,并使用你的自定义后端。
访问缓存
随时获取当前启用的缓存实例:
$cache = Queuety::cache();
$cache->set( 'my_key', 'my_value', 60 );
$value = $cache->get( 'my_key' );
这会返回当前启用的后端(MemoryCache、ApcuCache 或你的自定义实现)。