快取元件
Cache 元件提供涵蓋從簡單到進階快取需求的功能。它原生實作 PSR-6 和快取合約,以達到最佳的互操作性。它專為效能和彈性而設計,並為最常見的快取後端提供即用型适配器。它透過鎖定和提前過期,實現基於標籤的失效和快取失效保護。
提示
此元件也包含适配器,可在 PSR-6 和 PSR-16 之間轉換。請參閱PSR-6 和 PSR-16 快取之間互操作性的适配器。
安裝
1
$ composer require symfony/cache
注意
如果您在 Symfony 應用程式外部安裝此元件,您必須在您的程式碼中引入 vendor/autoload.php
檔案,以啟用 Composer 提供的類別自動載入機制。請閱讀這篇文章以瞭解更多詳細資訊。
快取合約
所有适配器都支援快取合約。它們僅包含兩個方法:get()
和 delete()
。沒有 set()
方法,因為 get()
方法同時取得和設定快取值。
您需要做的第一件事是實例化快取适配器。在此範例中使用 FilesystemAdapter
1 2 3
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
現在您可以使用此物件检索和刪除快取資料。get()
方法的第一個參數是一個鍵,一個任意字串,您將其與快取值關聯,以便稍後可以检索它。第二個參數是一個 PHP 可呼叫物件,當在快取中找不到鍵時執行它,以產生並傳回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
use Symfony\Contracts\Cache\ItemInterface;
// The callable will only be executed on a cache miss.
$value = $cache->get('my_cache_key', function (ItemInterface $item): string {
$item->expiresAfter(3600);
// ... do some HTTP request or heavy computations
$computedValue = 'foobar';
return $computedValue;
});
echo $value; // 'foobar'
// ... and to remove the cache key
$cache->delete('my_cache_key');
注意
使用快取標籤一次刪除多個鍵。在快取失效 中閱讀更多資訊。
阻擋快取失效
快取合約也內建了阻擋快取失效功能。這將消除快取冷啟動時的 CPU 峰值。如果一個範例應用程式花費 5 秒鐘計算快取 1 小時的資料,並且每秒存取此資料 10 次,這表示您主要會命中快取,一切都很好。但 1 小時後,我們收到 10 個針對冷快取的新請求。因此資料會再次被計算。下一秒鐘,同樣的事情發生了。因此,在快取再次變暖之前,資料會被計算約 50 次。這就是您需要阻擋快取失效的地方。
第一個解決方案是使用鎖定:僅允許一個 PHP 程序(在每個主機的基礎上)一次計算一個特定的鍵。鎖定是預設內建的,因此您無需執行任何超出利用快取合約的操作。
第二個解決方案在使用快取合約時也是內建的:與其等待完整延遲後才使值過期,不如在其過期日期之前重新計算它。機率性提前過期演算法隨機偽造一個使用者的快取未命中,而其他使用者仍然可以獲得快取值。您可以使用 get() 的第三個可選參數(一個稱為「beta」的浮點值)來控制其行為。
預設情況下,beta 值為 1.0
,值越高表示越早重新計算。將其設定為 0
以停用提前重新計算,並將其設定為 INF
以強制立即重新計算
1 2 3 4 5 6 7 8 9
use Symfony\Contracts\Cache\ItemInterface;
$beta = 1.0;
$value = $cache->get('my_cache_key', function (ItemInterface $item): string {
$item->expiresAfter(3600);
$item->tag(['tag_0', 'tag_1']);
return '...';
}, $beta);
通用快取 (PSR-6)
要使用通用的 PSR-6 快取功能,您需要學習其關鍵概念
- 項目
- 作為鍵/值對儲存的單個資訊單元,其中鍵是資訊的唯一識別符,值是其內容;請參閱快取項目 文章以瞭解更多詳細資訊。
- 池
- 快取項目的邏輯儲存庫。所有快取操作(儲存項目、尋找項目等)都透過池執行。應用程式可以根據需要定義任意數量的池。
- 适配器
- 它實作實際的快取機制,以將資訊儲存在檔案系統、資料庫等中。此元件為常見的快取後端(Redis、APCu、PDO 等)提供多個即用型适配器。
基本用法 (PSR-6)
此元件的這部分是 PSR-6 的實作,這意味著其基本 API 與文件中定義的相同。在開始快取資訊之前,請使用任何內建的适配器建立快取池。例如,要建立基於檔案系統的快取,請實例化 FilesystemAdapter
1 2 3
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
現在您可以使用此快取池建立、检索、更新和刪除項目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// create a new item by trying to get it from the cache
$productsCount = $cache->getItem('stats.products_count');
// assign a value to the item and save it
$productsCount->set(4711);
$cache->save($productsCount);
// retrieve the cache item
$productsCount = $cache->getItem('stats.products_count');
if (!$productsCount->isHit()) {
// ... item does not exist in the cache
}
// retrieve the value stored by the item
$total = $productsCount->get();
// remove the cache item
$cache->deleteItem('stats.products_count');
有關所有支援的适配器的列表,請參閱快取池和支援的适配器。
資料封送處理 (序列化)
注意
封送處理和序列化是類似的概念。序列化是將物件狀態轉換為可以儲存的格式(例如,在檔案中)的過程。封送處理是將物件狀態及其程式碼庫都轉換為可以儲存或傳輸的格式的過程。
解封送處理物件會產生原始物件的副本,可能透過自動載入物件的類別定義。
Symfony 使用 *封送處理器*(實作 MarshallerInterface 的類別)在儲存快取項目之前處理它們。
DefaultMarshaller 預設使用 PHP 的 serialize()
函數,但您可以選擇使用 Igbinary 擴充功能中的 igbinary_serialize()
函數
1 2 3 4 5 6 7 8 9
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
$marshaller = new DeflateMarshaller(new DefaultMarshaller());
// you can optionally use the Igbinary extension if you have it installed
// $marshaller = new DeflateMarshaller(new DefaultMarshaller(useIgbinarySerialize: true));
$cache = new RedisAdapter(new \Redis(), 'namespace', 0, $marshaller);
還有其他封送處理器可以在儲存資料之前對其進行加密或壓縮。
7.2
在 Symfony 7.2 之前的版本中,當安裝 Igbinary 擴充功能時,預設使用 igbinary_serialize()
函數。從 Symfony 7.2 開始,您必須明確啟用 Igbinary 支援。