WordPress 對象緩存:Redis、Memcached 和本機 API

已發表: 2017-11-04

可以隨意擴展的企業級 WordPress 站點需要一種超越頁面和圖像的持久緩存機制,一種可以緩存實際 PHP 對象的機制。 儘管 WordPress 通過 WordPress 對象緩存提供對象緩存機制,但還有其他解決方案可以提供強大的槓桿作用和功能。 在我們進入所有這些之前,首先,我們需要了解對象緩存是什麼以及它在 PHP 中是如何工作的。

什麼是對象緩存?

PHP 是一種面向對象的語言。 它使用對象範式來構造代碼。 因此,您的 WordPress 站點由許多不同的 PHP 對象組成,這些對像不斷創建、實例化和銷毀(由內存管理器)。 創建和銷毀對象會產生開銷,尤其是在對像很多的情況下。 但是,由於它們代表核心功能,因此它們中的大多數往往會被大量重用。 這意味著每次應用程序再次需要它們時,都需要從一開始就實例化它們。

如果您可以緩存一個經常使用的實例化對象,這樣您就不需要一直銷毀和創建它會怎樣?

您可以使用 PHP 的serialise()函數將對像或原語轉換為可以存儲在內存或磁盤中以供以後訪問的數字表示(字節 blob)。 然後使用hash()函數計算字節 blob 的哈希數並存儲它們。 哈希作為鍵,字節塊作為值。 為了檢索它,您使用最初存儲為鍵的字節 blob 的計算哈希數。 您可以通過這種方式將任何內容(字符串、整數、對象、布爾值、數組等)轉換為值的可存儲表示。

例子:

$serialized = serialize( array ( 'test' ));

使用 unserialize() 執行相反的操作:

$original = unserialize ( $serialized );

一般來說,可以通過三種方式緩存對象:使用本機 WordPress 對象緩存、Transients API 或外部鍵值存儲,如 Redis 或 Memcached。

WordPress 對象緩存

WordPress 提供了兩個對象緩存 API:原生 WordPress 對象緩存和瞬態 API。 它們是相同的,雖然這可能會引起混淆,但其背後是有邏輯的。

原生 WordPress 對象緩存可以在緩存中存儲對象和原語,但默認情況下不能以持久方式存儲。 這意味著緩存發生在內存中,並且緩存的對像不會超出請求的生命週期。 因此,您不能在不同的頁面加載之間共享您的緩存對象。 您需要使用 Drop-Ins 提供您自己的商店實現,這些插件是可以擴展 WordPress 功能的“高級”插件。 您可以在 WordPress 儀表板上的插件列表中看到它們:

WordPress 插件

另一方面,Transients API 開箱即用。 您可以將與到期日期綁定的變量、數組、對象直接保存在數據庫中,並具有持久對象緩存。 但是,問題是當您的緩存對象過期時,它們仍保留在數據庫中佔用空間。 這意味著在維護數據庫時需要花費額外的開銷,每隔一段時間修剪一次過期的對象。

WordPress 會檢測您是否實現了自己的持久對象緩存,當它發現是這種情況時,會繞過對 Transients API 的調用並將其路由到 WordPress 對象緩存(因此它們相同的原因)。

開發人員可以實現自己的對象緩存,使用 WordPress 插件(稍後會詳細介紹)或我們自己的實現,如果是 Pressidium 客戶端。 默認情況下,我們沒有打開對象緩存,因為如果在錯誤的情況下使用這可能會導致性能下降。 對於 WordPress 網站中的對象緩存,沒有“一刀切”的解決方案。

Redis 和 Memcached

鍵值存儲不使用表和預定義的數據類型將信息存儲在 RDBMS 等記錄中。 它們旨在存儲和檢索鍵/值對,就像您在編程語言中找到的字典數據結構一樣。

這種存儲的一個很好的例子是 Redis。 除了字典數據結構外,它還支持許多其他數據結構,包括高級數據結構,例如帶有範圍查詢的排序集,以及帶有半徑查詢的地理空間索引。 它提供持久對象緩存

雷迪斯

Redis 不僅僅是一個鍵值對存儲或緩存。 它支持集群配置中的數據複製、腳本編寫和高可用性。 您還可以微調所需的磁盤持久性級別。 Redis 的好處是,如果你重新啟動,你的大部分緩存仍然在磁盤上,丟失的數據只是一小部分。 問題是,在重新啟動時,服務器將不得不重建緩存,這在大多數情況下會增加負載。 使用 Redis,這不會發生。 此外,過期的對象會立即​​從數據庫中刪除。 那裡也沒有管理開銷時間。

Redis Labs 有一個很好的頁面展示了 Redis 在企業中的用例:從超大數據集到全文搜索、實時序列、Spark 集成等等。

儘管所有這些功能都以復雜性為代價,並且在某些情況下可能以速度為代價,但優化您的 Redis Drop-In 代碼可以獲得相當多的收益。 不要忘記 Redis 會進行持久對象緩存這一事實,而 Memcached 不會,儘管它使用起來要簡單得多。

內存緩存

Memcached 是根據官網介紹的內存中高性能對象緩存系統,專為加速動態 Web 應用程序和減輕數據庫負載而設計。 它的使用也比 Redis 簡單直接得多。

由於專門設計用於對網頁進行對象緩存,並且它使用內存數據庫這一事實使其成為目前最快的對象緩存解決方案。 但是,正如我們之前提到的,如果您的服務器重新啟動,您的緩存就會失效。 在重建之前,您可能會遇到負載增加的情況。 但正如創建者所說:“將其視為您網站的短期記憶”,因此這取決於您首先要做什麼。

由於 Memcached 使用內存數據庫來保存緩存,因此在緩存 SQL 查詢、函數調用輸出等方面非常有效。

WordPress 插件

  • WP Redis,官方 Redis WordPress 插件。 支持 WP-CLI、集群和復制。
  • Redis 對象緩存 WordPress 的另一個後端 Redis 插件。
  • Memcached 對象緩存,Memcached 的後端。
  • Delete Expired Transients,這個插件從數據​​庫中刪除過期的瞬態對象。 它也支持多站點!

如何運行基準測試

我們這篇文章的重點是讓您對對象緩存感到興奮並開始自己進行修補。 您可以嘗試各種持久緩存實現,看看您的應用程序表現如何。 您可以使用 PHP 的 microsecond() 函數對調用進行基準測試。 例如:在調用 wp_cache_get( microsecond()之前和之後調用wp_cache_get() ,減去值並存儲結果。 對各種緩存實現執行此操作,並查看在哪些情況下您會注意到性能提升。

在 Pressidium,我們沒有默認啟用對象緩存,儘管這是可以請求的,但我們通常不建議從一開始就支持它。 我們運行測試並確保您的網站將從中受益。

結論

假設為了呈現一個頁面,應用程序需要讀取 2,000 個瞬態對象。 這意味著對數據庫進行 2,000 次讀取。 通過使用持久對象緩存系統,這 2,000 次讀取被卸載到鍵值存儲。 如果您使用 memcached,那麼您可能會在突然重啟時丟失所有緩存。 一般來說,Redis 可能不如 Memcached 快,但它的企業特性和持久性從長遠來看會讓您受益。

然而,一種尺寸並不適合所有人! 例如,我們已經看到 Redis 實例實際上減慢了網站的速度,而在其他情況下,它們的速度令人難以置信。 這與您的應用程序使用的許多對像有關:一般來說,如果您的應用程序使用幾個(比如說十幾個),您不會從對象緩存中獲得太多好處,在最壞的情況下,您將有網絡開銷。 但是,如果您的應用程序有數百個,那麼查看一下可能會有所回報。