memcached)php_memcache.dll / memcache.so)# 1. 伺服器端 sudo apt-get install memcached # 啟動:監聽 127.0.0.1:11211,64MB 記憶體 memcached -d -m 64 -u www-data -l 127.0.0.1 -p 11211 # 2. PHP 擴展 (二選一) # A. 較舊 memcache sudo apt-get install php-memcache # B. 推薦 memcached (支援 CAS、二進位協定、更好叢集) sudo apt-get install php-memcached # 3. 重載 PHP-FPM / Apache sudo systemctl reload php8.2-fpm
基礎 CRUD 操作 (以 Memcached 為例)
addServer('127.0.0.1', 11211); // 連接池選項 (生產建議) $mem->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT); $mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); $mem->setOption(Memcached::OPT_RETRY_TIMEOUT, 10); $mem->setOption(Memcached::OPT_CONNECT_TIMEOUT, 1000); // ms $mem->setOption(Memcached::OPT_POLL_TIMEOUT, 1000); // 寫入 $mem->set('user:1', ['name' => 'John', 'role' => 'admin'], 3600); // TTL 1小時 $mem->setMulti(['key1' => 'val1', 'key2' => 'val2'], 300); // 讀取 $user = $mem->get('user:1'); $vals = $mem->getMulti(['key1', 'key2']); // 更新 (僅存在時) $mem->replace('user:1', ['name' => 'Johnny'], 3600); // 原子遞增/遞減 $mem->increment('counter'); // 1 $mem->decrement('counter'); // 0 // 刪除 $mem->delete('user:1'); $mem->flush(); // 清空所有 (謹慎使用) // CAS (Check-And-Set) 樂觀鎖 $cas = 0; $val = $mem->get('key', null, $cas); $mem->cas($cas, 'key', $newVal); // 失敗回傳 false,需重試進階序列化與壓縮
$mem->setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_IGBINARY); // 高效二進位 $mem->setOption(Memcached::OPT_COMPRESSION, true); // 自動壓縮大值 $mem->setOption(Memcached::OPT_COMPRESSION_THRESHOLD, 1024); // >1KB 壓縮 $mem->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_ZSTD); // PHP 8.0+ Zstd分散式架構設計
一致性雜湊 (Consistent Hashing)
Memcached 客戶端內建 Ketama 演算法,**增減節點只影響少量鍵遷移**。
$mem->addServers([ ['10.0.0.1', 11211, 33], // 權重 33% ['10.0.0.2', 11211, 33], ['10.0.0.3', 11211, 34], ]);鍵設計原則
project:module:type:id (如 shop:product:detail:123)counter:1 → counter:1:shard0~9 讀取時隨機/輪詢| 風險 | 對策 | 實作 |
|---|---|---|
| 未授權存取 (預設無認證) | **內網隔離** + 防火牆 | 只綁定內網 IP -l 10.0.0.1,SG/iptables 僅放行應用伺服器 IP |
| 資料竊聽 | 加密傳輸 | 啟用 SASL (需編譯支援) 或走 VPN/VPC 私有網路 |
| 記憶體耗盡 | 限制記憶體 + 淘汰策略 | -m 2048 限制 2GB,LRU 自動淘汰 |
| 鍵遍歷洩露 | 無 KEYS 指令,但 stats items 可見前綴 |
鍵命名不洩露業務敏感資訊 |
function getProduct(int $id): array {
$key = "shop:product:$id";
$data = $mem->get($key);
if ($data !== false) return $data; // 命中
// 未命中:查 DB
$data = $db->query("SELECT * FROM products WHERE id=?", [$id])->fetch();
if ($data) {
$mem->set($key, $data, 3600); // 回寫快取
}
return $data;
}
function updateProduct(int $id, array $data): bool {
$ok = $db->update('products', $data, ['id' => $id]);
if ($ok) {
$mem->delete("shop:product:$id"); // 失效快取 (或直接 set 新值)
}
return $ok;
}
# 即時統計 memcached-tool 127.0.0.1:11211 stats # 關注:get_hits / get_misses (命中率)、evictions (淘汰數)、bytes (記憶體使用)、curr_connections