PHP 有兩個 Memcached 客戶端擴展,**名稱極易混淆**,配置方式完全不同。本文徹底釐清差異,提供標準化配置模板。
| 維度 | memcache (舊) | memcached (新,推薦) |
|---|---|---|
| PECL 套件名 | memcache | memcached |
| 底層庫 | 自實現協議 | libmemcached (C 庫) |
| Session Handler 名稱 | `memcache` | `memcached` |
| save_path 格式 | `tcp://host:port` | `host:port` (無協議前綴) |
| 功能豐富度 | 基礎 | 完整 (CAS、二進制協議、SASL、一致性雜湊) |
| 維護狀態 | 低頻更新 | 活躍維護 |
| PHP 8+ 支援 | 有限 | 完整 |
extension=memcache.so session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211?persistent=1&weight=2&timeout=1&retry_interval=15" ; 多伺服器用逗號分隔 ; session.save_path = "tcp://10.0.1.10:11211?persistent=1, tcp://10.0.1.11:11211?persistent=1"
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://127.0.0.1:11211?persistent=1&weight=2');
session_start();
extension=memcached.so session.save_handler = memcached session.save_path = "127.0.0.1:11211" ; 多伺服器 ; session.save_path = "10.0.1.10:11211, 10.0.0.11:11211" ; 帶權重 (memcached 3.0+) ; session.save_path = "10.0.1.10:11211:10, 10.0.1.11:11211:20" ; 關鍵調優 memcached.sess_prefix = "myapp_" ; Key 前綴,防衝突 memcached.sess_binary_protocol = On ; 二進制協議 (效能更好) memcached.sess_consistent_hash = On ; 一致性雜湊 (擴容不遷移) memcached.sess_locking = On ; Session 鎖 (防併發競態) memcached.sess_lock_wait = 150000 ; 鎖等待微秒 (150ms) memcached.sess_lock_max_wait = 0 ; 最大等待 (0=不限制) memcached.sess_lock_retries = 5 ; 重試次數
ini_set('session.save_handler', 'memcached');
ini_set('session.save_path', '127.0.0.1:11211');
// 進階選項需 php.ini 或 Memcached 物件設定
$memcached = new Memcached();
$memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // 一致性雜湊
// 注意:Session handler 使用內部連接池,無法直接注入 $memcached
'driver' => 'memcached',
'connection' => 'session',
// config/database.php
'memcached' => [
'session' => [
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
'persistent_id' => 'session_pool',
'options' => [
Memcached::OPT_BINARY_PROTOCOL => true,
Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
Memcached::OPT_TCP_NODELAY => true,
Memcached::OPT_CONNECT_TIMEOUT => 2000,
Memcached::OPT_POLL_TIMEOUT => 2000,
],
],
],
framework:
session:
handler_id: session.handler.memcached
cookie_secure: true
cookie_httponly: true
gc_probability: 0 # 交給 memcached 過期
services:
memcached.session:
class: Memcached
calls:
- [setOption, [OPT_BINARY_PROTOCOL, true]]
- [setOption, [OPT_LIBKETAMA_COMPATIBLE, true]]
- [addServer, ['%env(MEMCACHED_HOST)%', '%env(int:MEMCACHED_PORT)%', 100]]
session.handler.memcached:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler
arguments: ['@memcached.session', { prefix: 'sf_sess_' }]
# 1. 檢查 Session 是否寫入 telnet 127.0.0.1 11211 get memc.sess.key.# memcache 前綴 get myapp_ # memcached 自定義前綴 # 2. PHP 代碼驗證 addServer('127.0.0.1', 11211); $key = 'myapp_' . $sessionId; // 依前綴調整 var_dump($mem->get($key));
| 參數 | 預設 | 建議 | 說明 |
|---|---|---|---|
sess_locking | On | On | 防止同一 Session 併發請求競態,必須開啟 |
sess_lock_wait | 150000 | 100000-500000 | 獲取鎖失敗後等待微秒,避免忙等待 |
sess_lock_retries | 5 | 3-10 | 重試次數,超過拋出鎖定異常 |
sess_consistent_hash | Off | On | 一致性雜湊,增減節點不大規模遷移 Key |
sess_binary_protocol | Off | On | 二進制協議,減少解析開銷,支援 SASL |
sess_prefix | memc.sess.key. | 專案唯一前綴 | 多專案共用叢集時防 Key 衝突 |
**新專案請直接使用 `memcached` (基於 libmemcached) 擴展**,配置二進制協議、一致性雜湊、Session 鎖、自定義前綴。舊專案維護 `memcache` 時注意格式差異。將 Session 遷移至 Memcached 是 PHP 水平擴展的關鍵一步,務必驗證寫入、讀取、鎖行為、過期清理全鏈路正常。