Manual:内存缓存
memcached是一種記憶體內部的物件型儲存空間,MediaWiki可用於快取值,以減少執行耗費資源的運算需求、並降低資料庫的伺服器的負載。
何時使用
對於由單一伺服器所代管的小型網站而言,安裝Memcached可能並不值得費心去做。 對於這樣的情況,請考慮將MediaWiki設定為改用PHP的APCu作為主要的物件型儲存空間。 對於維基百科這類的大型網站、以及一般是由多台網頁伺服器代管的維基系統,Memcached是MediaWiki物件快取常見的選擇。
有關MediaWiki快取選項的更多資訊,請參閱手冊:效能調校§物件快取
安装Memcached
大多數適用於 Linux 和 macOS 的套件管理程式皆提供可直接使用的 Memcached 套件(包含 Debian、Fedora 及 Ubuntu 系統)。
若您的發行版沒有現成可用的套件,您可能需要從原始碼去編譯,請至memcached.org下載原始碼。 要從原始碼編譯,您還需要libevent。 Memcached與libevent皆為採用BSD型式的授權條款所發佈的開源專案。
更多關於Memcached的資訊,請參閱維基百科上的「Memcached」條目。
安全性
Memcached 無任何安全性防護或驗證機制。 請確保您的伺服器已設置適當的防火牆,且用於memcached伺服器的通訊埠不得對外開放公開存取。 否則,任何網路上的使用者都能將資料寫入您的快取、或是從中讀取資料。
某個熟悉 MediaWiki 內部運作的攻擊者可藉此取得開發者權限,他不僅能刪除維基資料庫中的所有資料,還能取得所有使用者的密碼哈希值與電子郵件地址。
Memcached的PHP客戶端
截至本文(MediaWiki 1.27)撰寫時,MediaWiki使用純PHP編寫的 memcached 客戶端(基於Ryan T. Dean的工作成果)。
它也支持php-memcachedPECL擴充功能。
要在 MediaWiki 中使用 Memcached,PHP 必須以 --enable-sockets 選項編譯(此為預設值)。
若欲使用PECL 基礎memcached客戶端,請將 $wgMainCacheType 及相關的快取變數設定為 'memcached-pecl' 而非 CACHE_MEMCACHED。此 PECL memcached 客戶端支援若干附加功能,例如 SASL 授權與連線池化,其對部份的使用者可能有所助益。
若要進一步瞭解如何為MediaWiki的不同部份選擇Memcached作為後端,請參閱Manual:Caching。
设置
若您想從小規模開始,只需在您的網頁伺服器上運行一個 Memcached:
memcached -d -l 127.0.0.1 -p 11211 -m 64
(以常駐模式運行,僅可透過環回介面存取,使用端口 11211,最多佔用 64MB 記憶體)
請在您的LocalSettings.php檔案中設定:
$wgMainCacheType = CACHE_MEMCACHED;
$wgParserCacheType = CACHE_MEMCACHED; // 非必填
$wgMessageCacheType = CACHE_MEMCACHED; // 非必填
$wgMemCachedServers = [ '127.0.0.1:11211' ];
$wgSessionsInObjectCache = true; // 非必填--已在1.33版以上移除
$wgSessionCacheType = CACHE_MEMCACHED; // 非必填
那時該維基應就會使用 memcached 來快取各種資料。 若要使用多台伺服器(多台實體分離的箱型設備、或在單台大型記憶體x86/Power箱型設備的機器上的多個快取),只需將更多項目加入陣列即可。 若要增加某台伺服器的權重(例如因其記憶體容量是其他伺服器的兩倍,而您希望平均分配使用量),請將該伺服器的入口設為子陣列:
$wgMemCachedServers = [
'127.0.0.1:11211', // 這個箱型設備裡有1GB
[ '192.168.0.1:11211', 2 ] // 其他箱型設備裡有2GB
];
SELinux
對於SELinux的系統,Memcached 提供多種安全策略選項。 要讓 Apache (httpd) 能存取 Memcached,您必須設定以下的政策:
setsebool -P httpd_can_network_memcache 1
故障排除
儲存過程中的工作階段資料損失
若您將工作階段資料儲存於 memcached 中,且使用者在嘗試儲存編輯內容時會間歇性地看到此訊息:
对不起!由于会话数据丢失,我们无法处理您的编辑。
您可能已经退出。请核实您是否仍在登录,并重试。 如果仍然不能工作,尝试退出并重新登录,并检查您的浏览器是否允许来自该网站的cookie。
那麼您的其中一台或多台memcached伺服器可能存在組態錯誤的 /etc/hosts 檔案。
在每台的Memcached伺服器上,請確保該伺服器自身的主機名稱已映射至localhost:
127.0.0.1 servername.here localhost localhost.localdomain ...
否則,伺服器可能無法連接到其自身的memcached进程。
在程式碼中使用memcached
若您正在編寫一個執行很耗時的資料庫查詢的擴充功能,將資料快取至memcached可能會有助益。 取得memcached的句柄主要有以下幾種方式:
- …若您需要一個基於記憶體的共享快取,其具備有明確清除能力,用以儲存來自持久性來源的衍生值,就用上面這個
$cache = ObjectCache::getMainWANInstance()
- …若您需要一個基於記憶體、短暫性的儲存空間,該儲存空間不會在資料中心之間共享,就用上面這個
$cache = ObjectCache::getLocalClusterInstance()
- …若您需要一個基於記憶體、短暫性的快取,該快取不會在網頁伺服器之間共享,就用上面這個
$cache = ObjectCache::getLocalServerInstance()
- …若您需要任何可用的快取,其無論是否是資料中心專屬,甚至可以是一個使用SQL資料庫所模擬出來的快取,就用上面這個。 請注意,這些方法可能回傳與Redis、APC、MySQL、或其他儲存系統通訊的句柄。 「memcached」一詞有其歷史淵源,源自其API是圍繞在memcached有支援的簡易指令所定義的,以及,迄今為止,memcached通常仍是最佳的通用型快取儲存方案的此一事實。
$cache = wfGetCache( CACHE_ANYTHING )
具有特定需求(例如持久性)的擴充功能應定義新的組態設定,像是$wgMyExtCache或$wgMyExtWANCache。
使用快取的程式碼可將其分別傳遞至wfGetCache()和ObjectCache::getWANInstance()。
以下程式碼片段示範了如何將持續15分鐘的資料庫查詢結果快取至memcached中,然後執行查詢時,系統會優先從memcached取得結果、而不是從資料庫查詢。
class MyExtensionFooBars {
public function getPopularTen() {
$cache = ObjectCache::getMainWANInstance();
return $cache->getWithSetCallback(
// 傳遞給wfMemcKey()的可變參數們就是被用來在memcached之中建立快取的鍵。
// 它必須是您正在儲存的查詢所獨有的。
// 第一個值通常是擴充功能名稱或元件名稱、然後接續的值會告訴您正在儲存的是哪個查詢。
$cache->makeKey( 'myextension', 'foobars', 'popular', '10' ),
// 快取 15 分鐘
$cache::TTL_MINUTE * 15,
// 快取未命中時用來產生值的函式
function ( $oldValue, &$ttl, &$setOpts ) {
$dbr = MediaWikiServices::getInstance()->getConnectionProvider()-> getReplicaDatabase();
// 根據資料庫複寫延遲去調整存留時間(TTL)
$setOpts = Database::getCacheSetOptions( $dbr );
$res = $dbr->select(
// 您的資料庫查詢指令在此處
// 請参见Database::select以获取更多文档
);
$data = array();
foreach ( $res as $row ) {
$data[] = array(
// 用我們從資料庫剛取得的資料來做點什麼。
// 例如,若我們要從 page 表格中查找 page_id,可以這樣做:
'id' => $row->page_id
);
}
return $data;
}
);
}
}
BagOStuff抽象類別與WANObjectCache類別定義並記錄了所有可用函式:
之前的开发笔记
概括來說,我們希望可以將大量資料倒入快取,在需要時隨時調用、且在資料變更時自動清除過期內容。
過期模式
- 明確的過期時間:memcached讓我們可以在儲存物件時設定其過期時間。 時間到期之後,再次對該物件的請求將發現物件已過期,然後不返回任何結果給我們。
- 優點:作為最後手段的後備方案,讓那些「可能」被錯誤更新的資料最終從快取中移除
- 缺點:我們必須事先知道它何時會失效。當我們面對的是用戶的編輯時,這點很難做到!
- 當我們知道正在執行的操作會導致快取物件失效,卻無法在執行過程中同步更新這些物件時,應主動清除快取物件
- 優點:相當簡單;該項目將在下次需要時從資料庫重新載入並重新快取
- 缺點:若此操作會影響大量的相關項目(例如建立或刪除頁面會導致連結/斷鏈的資料表失效,並清除所有連結該頁面的頁面渲染HTML快取),我們可能需要逐一追蹤這些項目並進行大量的更新作業。
- 在快取的物件上加入時間戳記,並根據依存關係自行設定過期機制
- 優點:可透過更新單一個所依賴的節點,讓多個物件同時過期
- 缺點:需要載入更多的內容;多重的依存關係可能更難處理
問答集
問:我能否在Memcached伺服器上以鍵或是正規表達式的某個部份進行搜尋?
A:不行,您只能搜尋精確的鍵。若需進一步了解可執行的操作,請參閱Memcached協定。
問:我可以讓多個維基指向同一個 Memcached 伺服器嗎?
A:可以,只要每一個都有不同的維基識別碼($wgDBname)。 在這種情境下,某些特定的快取的鍵會被刻意地共享出來,例如流量限制相關功能的設定。