首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP Session 儲存至 Memcached/Memcached 完整配置指南:兩大擴展差異與最佳實踐

     編輯:PHP 綜合知識

前言:memcache vs memcached 擴展,傻傻分不清?

PHP 有兩個 Memcached 客戶端擴展,**名稱極易混淆**,配置方式完全不同。本文徹底釐清差異,提供標準化配置模板。

兩大擴展對比表

維度memcache (舊)memcached (新,推薦)
PECL 套件名memcachememcached
底層庫自實現協議libmemcached (C 庫)
Session Handler 名稱`memcache``memcached`
save_path 格式`tcp://host:port``host:port` (無協議前綴)
功能豐富度基礎完整 (CAS、二進制協議、SASL、一致性雜湊)
維護狀態低頻更新活躍維護
PHP 8+ 支援有限完整

配置模板:memcache 擴展 (舊專案維護)

php.ini 全域

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();

配置模板:memcached 擴展 (新專案首選)

php.ini 全域

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

框架整合配置

Laravel (config/session.php)

'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,
        ],
    ],
],

Symfony (framework.yaml)

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));

關鍵調優參數深度解析 (memcached 擴展)

參數預設建議說明
sess_lockingOnOn防止同一 Session 併發請求競態,必須開啟
sess_lock_wait150000100000-500000獲取鎖失敗後等待微秒,避免忙等待
sess_lock_retries53-10重試次數,超過拋出鎖定異常
sess_consistent_hashOffOn一致性雜湊,增減節點不大規模遷移 Key
sess_binary_protocolOffOn二進制協議,減少解析開銷,支援 SASL
sess_prefixmemc.sess.key.專案唯一前綴多專案共用叢集時防 Key 衝突

避坑指南

  • 混用兩個擴展:專案中**只能安裝/啟用一個**,否則 `session.save_handler` 衝突
  • save_path 格式錯誤:memcache 用 `tcp://`,memcached **不帶協議前綴**
  • Session 鎖導致請求阻塞:長耗時請求調用 `session_write_close()` 釋放鎖
  • Key 過期時間與 gc_maxlifetime 不一致:確保 `session.gc_maxlifetime` ≤ Memcached 過期設定
  • 防火牆/安全組未放行 11211**應用伺服器需能 TCP 連接 Memcached 端口

結語

**新專案請直接使用 `memcached` (基於 libmemcached) 擴展**,配置二進制協議、一致性雜湊、Session 鎖、自定義前綴。舊專案維護 `memcache` 時注意格式差異。將 Session 遷移至 Memcached 是 PHP 水平擴展的關鍵一步,務必驗證寫入、讀取、鎖行為、過期清理全鏈路正常。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved