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

Memcached 深度剖析:架構、記憶體管理、協議、一致性雜湊、BSM_Memcache 擴展

     編輯:PHP 相關知識

Memcached 定位

  • **分散式**記憶體物件快取,基於網路 (TCP/UDP) 服務,非本地共享記憶體 (區別於 APC/Shm)。
  • 適用場景:DB 前端快取、跨服務 Session/Token 共享、熱點資料緩衝。
  • **不適用**:單機本地快取 (網路開銷大於收益)、持久化儲存 (重啟資料丟失)。

啟動流程 (memcached.c main)

  1. `settings_init()` 初始化預設參數。
  2. 解析命令列參數覆蓋設定。
  3. 設定 `RLIMIT_NOFILE` (最大檔案描述符)。
  4. 建立 TCP/UDP/Unix Socket 監聽。
  5. 檢查非 root 身份 (安全)。
  6. Daemon 化 (`-d` 參數) → `daemon()` fork + `setsid` + 重導向標準流到 `/dev/null`。
  7. 初始化核心子系統:`item`、`event` (libevent)、`stats`、`hash` (一致性雜湊)、`conn`、 `slab` 分配器。
  8. 訊號處理、刪除佇列、PID 檔寫入。
  9. 進入 `drive_machine` 事件迴圈 (libevent `event_base_loop`)。

記憶體管理:Slab Allocator (核心亮點)

設計動機

避免頻繁 `malloc/free` 造成碎片與鎖爭用,預先向 OS 申請大塊 (預設 1MB) Slab,切分為固定大小 Chunk。

關鍵資料結構

  • `slabclass[0..MAX_NUMBER_OF_SLAB_CLASSES-1]` (1.2 版預設 200 類)。
  • 每 class 固定 `chunk_size`,遞增因子 `factor=1.25` (可調 `-f`)。
  • `chunk_size[0] = 96 bytes` (含 `item` 結構體),之後 `chunk_size[n] = ceil(chunk_size[n-1] * factor)` 對齊 8 位元組。

分配流程

  1. 客戶端 `set` → 計算 `key+value+flags+expire` 總長 → 找到最小滿足的 `slabclass`。
  2. 該 class `slots` 鏈表有空閒 chunk → 直接取用。
  3. 無空閒 → 向 OS 申請新 1MB Slab → 切分掛入 `slots` → 取用。
  4. LRU 淘汰:同 class 內按 `time` 排序,尾部淘汰 (非全域 LRU)。

優缺點

網路模型:libevent + 狀態機

  • 單執行緒 (預設) + 非阻塞 I/O,`drive_machine` 根據 `conn->state` 處理讀/寫/關閉。
  • 支援多執行緒 (`-t`):主執行緒 `accept` → 分派到 worker 執行緒佇列,各自獨立 event_base。
  • 協議:簡單文本行協議 (`set key flags exptime bytes\r\nvalue\r\n`),二進制協議 (1.3+) 減少解析開銷。

分散式:Client 端一致性雜湊

**伺服器端無叢集感知**,分散邏輯完全在 Client Library:

  1. 將 Key 雜湊 (Ketama 演算法) 映射到 0~2^32-1 環。
  2. 每台實體伺服器對應 100-200 個虛擬節點 (權重可調)。
  3. 順時針找最近虛擬節點 → 該實體伺服器。
  4. 增減節點僅影響少數 Key 重新映射 (單調性)。

BSM_Memcache (PHP 擴展) 關鍵實現

  • C 層封裝 `libmemcached`,提供 `Memcache` 類相容介面 + 新增 `getMulti`、`setMulti` 批次操作。
  • 連線池管理:`persistent_id` 區分進程間共享連線,避免 PHP-FPM 重複建連。
  • 序列化策略:`igbinary` > `msgpack` > `php` (可配置 `memcache.serializer`)。
  • 壓縮:`MEMCACHE_COMPRESSED` 旗標觸發 `zlib` 壓縮,閾值 `memcache.compress_threshold` (預設 20KB)。

調優檢查清單

  1. `-m` 記憶體上限 (預設 64MB,生產建議 2-4GB/進程)。
  2. `-f` 增長因子 (1.1-1.25,資料長度分佈均勻可調小)。
  3. `-t` 執行緒數 (CPU 核心數,超執行緒不建議超過物理核心)。
  4. 監控 `stats`:`get_hits/get_misses`、 `evictions`、 `bytes_used/limit_maxbytes`、 `curr_connections`。
  5. Client 端:連線池復用、批次 `getMulti`、`setMulti` 減少 RTT、關閉 `no_delay` (Nagle) 降低延遲。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
優點缺點
O(1) 分配/釋放,無碎片 (內部碎片僅 < factor)內部碎片浪費:小值存大 chunk (如 100B 存 136B chunk)
鎖粒度細 (每 class 一把鎖),高併發擴展性好無法跨 class 借用記憶體,導致部分 class OOM 而其他 class 閒置