ql/mcp-cache

Quicken Loans PHP项目简单的缓存标准

此软件包的规范存储库似乎已消失,因此该软件包已被冻结。

3.1.0 2019-04-13 19:17 UTC

This package is auto-updated.

Last update: 2024-01-20 15:16:23 UTC


README

CircleCI Latest Stable Version License

Quicken Loans PHP项目简单的缓存标准。

我们更喜欢比PSR-6缓存接口提供的更简单的缓存协议。此软件包与草案PSR-16 Simple Cache有许多相似之处。如果此PSR被接受,我们将更新此软件包以确保兼容性。

安装

composer require ql/mcp-cache ~3.0

目录

用法

CacheInterface 只有两个方法 - getset

获取

public function get($key);

获取接受任何字符串作为键并查找数据。

请注意
  • 缺失的数据将返回 null。一个值为 null 的缓存命中与缓存未命中之间没有区别。
  • 在存储之前序列化对象不是必需的。序列化将由每个缓存实现进行优化。

设置

public function set($key, $value, $ttl = 0);

在缓存中设置数据。将返回一个布尔值以指示数据是否已保存。

请注意
  • 资源不能被缓存。
  • TTL 是数据应该存在直到过期的秒数。TTL 为 0 将永远不会使数据过期。

CachingTrait

提供 CachingTrait 以简化将可选缓存添加到您的类中。

QL\MCP\Cache\CachingTrait 将以下私有方法添加到您的特性消费者中

/**
 * @return CacheInterface|null
 */
private function cache();

/**
 * @param string $key
 * @return mixed|null
 */
private function getFromCache($key);

/**
 * @param string $key
 * @param mixed $value
 * @param mixed $ttl
 * @return null
 */
private function setToCache($key, $value, $ttl = 0);

如果您想直接访问缓存,请使用 $this->cache()。然而,通常并不需要这样做。如果未设置缓存器,则 getset 方法将优雅地失败并返回 null

还添加了以下公共方法

/**
 * @param CacheInterface $cache
 * @return null
 */
public function setCache(CacheInterface $cache);

/**
 * @param int $ttl
 * @return null
 */
public function setCacheTTL($ttl);

以下是一个示例

use QL\MCP\Cache\CachingTrait;

class MyRepo
{
    use CachingTrait;

    public function load()
    {
        if ($cached = $this->getFromCache('cachekey')) {
            return $cached;
        }

        // get data from service
        $data = $this->callService();

        $this->setToCache('cachekey', $data);
        return $data;
    }
}

Symfony DI 的设置示例

services:
    cache:
        class: 'QL\MCP\Cache\PredisCache'
        arguments: ['@predis']
    repo:
        class: 'MyRepo'
        calls:
            - ['setCache', ['@cache']]
            - ['setCacheTTL', [3600]]

PHP 的设置示例

$cacher = new PredisCache($predis);

$repo = new MyRepo;
$repo->setCache($cacher);
$repo->setCacheTTL(3600);

为什么使用这个?

  • 减少样板代码
  • 简化缓存

它允许您以最少的样板代码启用或禁用缓存。如果您从未设置缓存,则您的类中的所有缓存操作都将优雅地失败。

请注意,您可以为您类的 全局 ttl 设置一个值。如果在设置数据时提供了 ttl,则将使用该 ttl。如果没有提供,则将使用全局 ttl。如果全局 ttl 从未设置,则不会使用任何 ttl。

实现

MemoryCache

MemoryCache 是一个非常基本的缓存,用于缓存只在请求生命周期内存在的数据。此缓存忽略 ttl

use QL\MCP\Cache\MemoryCache;

$cache = new MemoryCache

// Store data
$cache->set('key', $data);

// Store data with expiration of 10 minutes  - note that ttl is ignored for this cacher
$cache->set('key', $data, 600);

PredisCache

此缓存将使用 predis 在 redis 中存储数据。

可以提供一个可选的后缀来对缓存键进行混淆。这可以用于在代码推送或其他配置更改之间使整个缓存无效。

将键设置为 null 将删除键,而不是将值设置为 null。使用 predis 缓存器无法存储 null 值。

use Predis\Client;
use QL\MCP\Cache\PredisCache;

$predis = new Client;
$suffix = '6038aa7'; // optional
$cache = new PredisCache($predis, $suffix);

// Store data
$cache->set('key', $data);

// Store data with expiration of 10 minutes
$cache->set('key', $data, 600);

APCCache

此缓存将在 APC 用户缓存空间中存储项。可以调用 APCCache::setMaximumTtl($ttl) 方法设置最大 TTL。

use QL\MCP\Cache\APCCache;
use QL\MCP\Common\Time\Clock;

$cache = new APCCache(new Clock());

// Optionally, set the maximum TTL to 10 minutes
$cache->setMaximumTtl(600);

// Store data
$cache->set('key', $data);

// Store data with an expiration of 10 minutes
$cache->set('key', $data, 600);

// Retrieve data
$data = $cache->get('key');

MemcachedCache

此缓存将使用 pecl-memcached 在 memcached 中存储数据。它还与 AWS ElastiCache Cluster Client 兼容,这是一个用于 pecl-memcache 的替代品,支持自动发现。

参见 PHP.NET Memcached 书籍

MemcacheCache

此缓存将使用 pecl-memcache 在 memcached 中存储数据。

参见 PHP.NET Memcache 书籍

Stampede Protection

在高负载服务的情况下,当缓存过期或被刷新时,许多请求尝试重新生成缓存,可能会导致依赖系统出现狗群效应,尤其是如果重新生成缓存数据的成本很高。这通常是在高负载下,缓存数据在许多请求之间共享时的问题。

存在几种防止此现象的方法,对于 MCP 缓存,我们实现了 概率性提前过期

使用这种方法,当剩余的 TTL 接近过期时,应用程序从 get 返回 缓存未命中 的随机概率越来越高。在这种情况下,只有一小部分用户会尝试重新生成缓存,而不是每个请求。

具有 Stampede Protection 的缓存实现

注意:默认情况下,stampede protection 是 禁用 的。

代码示例

use QL\MCP\Cache\APCCache;

$cache = new APCCache;
$cache->enableStampedeProtection();

// Customize beta and delta (not recommended).
$cache->setPrecomputeBeta(5);
$cache->setPrecomputeDelta(10);

// use cache as normal
$cache->set('test', 'value', 60);

示例缓存 Stampede Protection

Beta = 5
Delta = TTL 的 10%

设置一个 60 秒 TTL 的值并运行 1000 次测试。

TTL 剩余 百分位数 提前过期 百分比
25s 60% 1000 个中的 0 个 0%
20s 66% 1000 个中的 10 个 1%
15s 75% 1000 个中的 40 个 4%
6s 90% 1000 个中的 300 个 30%
3s 95% 1000 个中的 500 个 50%

参考