環境需求
- 安裝 Memcached 服務端
- PHP 安裝
memcache 或 memcached 擴展 (建議較新的 memcached,基於 libmemcached)
核心程式碼 (使用 memcache 擴展)
connect('127.0.0.1', 11211)) {
die('連線失敗');
}
// 1. 寫入 (set) - 可存字串、陣列、物件,不可存資源
$key = 'user:1001';
$val = ['name' => '小明', 'age' => 25, 'tags' => ['php', 'go']];
if ($mem->set($key, $val, MEMCACHE_COMPRESSED, 60)) { // 60 秒過期
echo "寫入成功\n";
}
// 2. 讀取 (get)
$data = $mem->get($key);
var_dump($data);
// 3. 更新 (replace) - key 必須存在才會成功
$mem->replace($key, ['name' => '小明', 'age' => 26], MEMCACHE_COMPRESSED, 60);
// 4. 刪除 (delete)
$mem->delete($key);
// 5. 關閉連線
$mem->close();
進階操作
| 方法 | 說明 |
add() | Key 不存在才寫入,存在則失敗 (適合鎖機制) |
cas() | Compare-And-Swap 樂觀鎖,需搭配 get() 取得 token |
increment()/decrement() | 原子性數值增減 (計數器) |
getStats() | 取得伺服器統計資訊 |
flush() | 清空所有快取 (慎用) |
CAS 樂觀鎖範例 (防止並發覆蓋)
connect('127.0.0.1', 11211);
$key = 'counter';
// 初始化
$mem->set($key, 0);
for ($i = 0; $i < 10; $i++) {
// 模擬併發:實際應用中這裡會是多個行程同時執行
$success = false;
while (!$success) {
$val = $mem->get($key);
$token = $mem->getCasToken(); // 取得版本號
$newVal = $val + 1;
$success = $mem->cas($token, $key, $newVal);
if (!$success) usleep(10000); // 衝突則短暫等待重試
}
}
echo "最終值: " . $mem->get($key); // 應為 10
常見問題
- 資料序列化:預設用 PHP serialize,跨語言建議改用 JSON/MessagePack (memcached 擴展支援
setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_JSON))。
- 連線池:長連線重複使用,避免頻繁
connect/close。
- Key 命名:加前綴區分業務 (如
user:1001、cache:article:55),避免衝突。
- 過期策略:LRU 淘汰機制,記憶體不足時自動移除最久未使用項目。