Memcache 是高性能分布式內存對象緩存系統,通過在內存中維護巨大的 HashTable,以鍵值對形式存儲任意數據(字符串、對象、數組等),廣泛用於緩存數據庫查詢結果、Session 存儲、頁面片段、API 響應等場景,有效降低數據庫負載、提升響應速度。PHP 提供 Memcache 類(面向對象)與 memcache_* 函數(面向過程)兩套接口,本文系統梳理所有核心方法。
| 分類 | 方法 | 功能 |
|---|---|---|
| 連接管理 | connect(host, port, timeout) | 建立非持久連接 |
pconnect(host, port, timeout) | 建立持久連接(進程級復用,減少握手開銷) | |
close() | 關閉連接 | |
| 服務器池管理 | addServer(host, port, persistent, weight, timeout, retry_interval, status, failure_callback) | 添加服務器到連接池(支持權重、故障回調) |
setServerParams(host, port, params) | 運行時修改服務器參數(權重、狀態等) | |
| 數據操作 | set(key, var, flag, expire) | 存儲/覆蓋數據(flag 自定義標記,expire 過期秒數,0=永久) |
add(key, var, flag, expire) | 僅當 key 不存在時存儲(原子操作,適合分布式鎖) | |
replace(key, var, flag, expire) | 僅當 key 存在時覆蓋 | |
get(key) / get(array(keys)) | 獲取單個/多個 key 的值(返回 false 表示不存在) | |
delete(key, timeout) | 刪除 key(timeout 秒內禁止重新 add,舊版本特性) | |
flush() | 清空服務器所有數據(慎用!生產環境建議禁用或限制權限) | |
| 計數器操作 | increment(key, value) | 原子遞增(value 預設 1),key 不存在返回 false |
decrement(key, value) | 原子遞減,不低於 0 | |
| CAS (Check-And-Set) | 需 Memcached 擴展(非 Memcache),支持樂觀鎖 | |
| 壓縮與優化 | setCompressThreshold(threshold, min_savings) | 啟用大值自動壓縮(threshold 字節以上,節省 min_savings% 才壓縮) |
| 狀態監控 | getStats(type, slabid) | 獲取服務器統計(items、slabs、sizes、malloc 等) |
getExtendedStats(type, slabid) | 獲取連接池所有服務器統計 | |
getVersion() | 獲取服務器版本字符串 | |
getServerStatus(host, port) | 獲取單服務器在線/離線狀態 | |
| 調試 | memcache_debug(0|1) | 開關調試輸出(全局影響) |
$mem = new Memcache();
// 添加多台服務器,權重分配負載
$mem->addServer('10.0.0.1', 11211, true, 1); // 權重 1
$mem->addServer('10.0.0.2', 11211, true, 2); // 權重 2,承擔雙倍流量
// 持久連接在 PHP-FPM 中跨請求復用,顯著減少連接建立延遲
注意:addServer 不會立即建立連接,首次操作時才連接。connect/pconnect 單服務器模式,不支持權重分發。
$mem->set('user:1001', ['name'=>'Tom', 'vip'=>true], 0, 3600); // 1h 過期
$mem->add('lock:order:888', 1, 0, 10); // 分布式鎖:10s 過期,獲取失敗則併發衝突
$mem->replace('counter:pageview', $newVal); // 必須存在才更新
expire > 2592000 (30天) 被視為 Unix 時間戳,建議統一用相對秒數。setCompressThreshold(10240, 0.2),超過 10KB 且壓縮率 > 20% 時自動 zlib 壓縮,節省內存帶寬。serialize(),取出時 unserialize()。避免存儲資源類型、閉包、PDO 對象。$keys = ['user:1', 'user:2', 'user:3'];
$users = $mem->get($keys); // 一次網絡往返獲取多個,返回找到的 key=>value 陣列
// 未命中 key 不在結果中,需自行判斷
$stats = $mem->getStats(); // 單服務器
// 關鍵指標:
// curr_items: 當前項目數
// bytes: 佔用內存字節
// get_hits / get_misses: 命中/未命中次數 → 命中率 = hits/(hits+misses)
// limit_maxbytes: 最大內存限制
// evictions: 驅逐數(LRU 淘汰),持續增長說明內存不足
$extended = $mem->getExtendedStats(); // 所有服務器
foreach ($extended as $server => $stat) {
echo "$server: 命中率 " . round($stat['get_hits']/($stat['get_hits']+$stat['get_misses'])*100, 2) . "%\n";
}
// php.ini
session.save_handler = memcache
session.save_path = "tcp://10.0.0.1:11211?persistent=1&weight=1, tcp://10.0.0.2:11211?persistent=1&weight=2"
// 或運行時設置
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://10.0.0.1:11211');
session_start();
多服務器 Session 自動分發,單點故障不丟失 Session(需配置故障轉移)。
| 特性 | Memcache (舊) | Memcached (新,libmemcached) |
|---|---|---|
| 類名 | Memcache | Memcached |
| CAS 樂觀鎖 | 不支持 | 支持 getDelayed() + cas() |
| 二進制協議 | 不支持 | 支持(性能更高) |
| 一致性哈希 | 客戶端實現 | 內建 Memcached::DISTRIBUTION_CONSISTENT |
| 多獲取 | get(array) | getMulti(array) / getDelayed() 異步 |
| 推薦度 | 維護舊項目 | 新項目首選 |
app:module:key。timeout(連接/讀寫),配合 retry_interval 避免長時間阻塞。Memcache 以極簡的鍵值接口、O(1) 讀寫性能、分布式水平擴展能力成為高併發架構的標配緩存層。精通其連接池管理、原子操作、壓縮策略、統計監控等核心 API,並理解Memcached 擴展的優勢,能讓你在緩存設計、Session 共享、分布式鎖、計數器等場景中游刃有餘。建議新項目直接使用 Memcached 擴展 + 一致性哈希 + CAS 樂觀鎖,構建更健壯的緩存體系。