架構全景
- 21 台服務器 部署 51 個 Memcached 實例
- 總緩存容量 254 GB,熱數據 175 GB(超過許多中型庫全量)
- 核心策略:分庫分表解決寫擴展 + 前端 Memcached 集群抗讀 + MySQL 主從讀寫分離
三層讀取鏈路
應用請求
↓
1. Memcached (目標 95% 命中)
↓ miss
2. MySQL Query Cache (目標 3% 命中)
↓ miss
3. InnoDB Buffer Pool / 磁盤 (僅 2%)
對比自家應用:若第 1 層命中 < 90%,架構即有優化空間。
為何不依賴 MySQL Query Cache?
| 缺陷 | 影響 |
| 單實例,受限於單機內存 | 無法水平擴展緩存容量 |
| 任何寫入導致相關表整個 Query Cache 失效 | 寫多讀少場景命中率極低 |
| 僅緩存結果集行,不支持對象/數組/計算中間態 | 應用層組裝對象仍需重複 CPU |
| 無分布式一致性機制 | 多實例無法共享 |
Memcached 關鍵優勢
- 分布式:一致性哈希擴容無停機
- 任意序列化對象:PHP 數組、JSON、Protobuf、甚至壓縮文件
- O(1) 讀寫:純內存、無解析、無鎖(單線程模型)
- 多語言客戶端:PHP/Java/Python/Go 共享緩存層
寫擴展:分庫分表
- 按業務域垂直拆分:用戶庫、訂單庫、日誌庫……
- 單庫再按鍵水平分片:
shard_id = user_id % N
- 避免單主寫入瓶頸與單點故障
讀擴展:MySQL 主從 + Memcached
- 主庫承擔寫、DDL、關鍵強一致讀
- 多從庫承擔報表、非核心查詢、備份
- 應用先查 Memcached,未命中再走從庫,回填 Memcached
運維避坑指南
- 緩存穿透:空值緩存短 TTL、布隆過濾器攔截不存在鍵
- 緩存雪崩:TTL 加隨機抖動、多級緩存、熔斷降級
- 數據一致性:寫雙刪(寫 DB → 刪 Cache → 延遲雙刷)或 Canal 訂閱 Binlog 異步刷新
- 單機實例數:建議每核 1-2 實例,避免上下文切換開銷
Fotolog 案例證明:Memcached 不是 MySQL 的補充,而是架構的核心讀層。將 95%+ 讀流量擋在內存層,MySQL 才能專注於寫入持久化與複雜查詢。