Memcached 作為 MySQL 前置緩存層,能將熱點查詢 QPS 提升 10-100 倍,降低 DB 負載 90% 以上。本文系統梳理 Memcached 與 MySQL 交互流程圖、四大操作模式、Key 設計規範、一致性保障策略、常見避坑指南。
[應用] --> (Key) --> [Memcached] --命中--> 返回數據
|--未命中--> [MySQL] --> 寫入 Memcached --> 返回數據
更新/新增/刪除:
[應用] --> [MySQL] 寫入成功 --> [Memcached] 刪除/更新對應 Key
$key = "thread_2009";
$val = $mem->get($key);
if ($val === false) {
$val = $db->query("SELECT * FROM thread WHERE id=2009");
$mem->set($key, $val, 0, 100); // 過期 100 秒
}
return $val;
$db->update("UPDATE thread SET views=views+1 WHERE id=2009");
$mem->delete("thread_2009"); // 刪除緩存,下次查詢自動回源載入新值
set 新值,避免併發更新時緩存版本倒退。$db->insert("INSERT INTO thread ... VALUES (2010, 'new')");
$mem->delete("thread_list_page_1"); // 刪除列表頁緩存
$mem->delete("thread_count"); // 刪除計數緩存
$db->delete("DELETE FROM thread WHERE id=2009");
$mem->delete("thread_2009");
$mem->delete("thread_list_page_1");
| 操作 | PHP Memcached | Python python-memcached | Java Spymemcached |
|---|---|---|---|
| 獲取 | $mem->get($key) | mc.get(key) | client.get(key) |
| 設置 | $mem->set($key, $val, $exp) | mc.set(key, val, time) | client.set(key, exp, val) |
| 刪除 | $mem->delete($key) | mc.delete(key) | client.delete(key) |
# 格式:業務域:實體:標識:屬性 thread:2009:detail thread:2009:comments:page:1 user:10001:profile order:202405:list:status:paid:page:1
| 坑點 | 後果 | 解決 |
|---|---|---|
| 緩存穿透(查不存在的 Key) | 請求直穿 DB,DB 掛掉 | 布隆過濾器攔截 / 緩存空值(短 TTL) |
| 緩存擊穿(熱 Key 過期瞬間併發) | 大量請求同時回源 DB | 互斥鎖重建 / 熱 Key 永不過期 + 異步更新 |
| 緩存雪崩(大量 Key 同一時間過期) | 流量洪峰打垮 DB | TTL 加隨機抖動 / 多級緩存 / 熔斷限流 |
| 併發更新髒讀 | 緩存版本倒退 | 先更新 DB 再刪緩存 / 版本號 CAS |
| 大 Value 超過 1MB | 寫入失敗/性能抖動 | 拆分 Value / 啟用壓縮 / 改用 Redis |
掌握「查詢回源、寫入刪緩存、Key 規範化、一致性策略」四大核心,即可構建穩健的 MySQL + Memcached 緩存體系。