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

PHP Memcached 基礎操作、分布式架構設計與安全加固全指南

     編輯:PHP 相關知識

基礎 CRUD 操作

<?php
$mem = new Memcached();
$mem->addServer('192.168.0.200', 11211); // 支持多台自動分片

// 存儲 (key, value, expiration 秒)
$mem->set('key1', 'First Value', 60);
$mem->set('key2', ['aaa','bbb','ccc','ddd'], 60);

// 讀取
$val1 = $mem->get('key1');
$val2 = $mem->get('key2');

// 替換 (僅鍵存在時成功)
$mem->replace('key1', 'Replaced Value', 60);

// 刪除
$mem->delete('key1');

// 原子增減 (僅限數值)
$mem->set('counter', 0);
$mem->increment('counter'); // 1
$mem->decrement('counter'); // 0

// 追加/前置 (字符串)
$mem->set('str', 'Hello');
$mem->append('str', ' World'); // 'Hello World'
$mem->prepend('str', 'Say ');  // 'Say Hello World'

// 獲取多鍵
$multi = $mem->getMulti(['key1', 'key2', 'counter']);

// 刷新所有 (慎用!)
$mem->flush();

// 關閉連接
$mem->close();
?>

Memcached 類 vs Memcache 類

特性Memcached (推薦)Memcache (舊)
類名MemcachedMemcache
二進制協議✅ 支持❌ 僅文本協議
多鍵獲取getMulti()不支持
CAS 操作✅ cas()❌
持久連接✅ addServer(..., true)✅
壓縮✅ setOption(OPT_COMPRESSION, true)✅
PHP 7+ 支持完美不再維護

分布式架構設計

一致性哈希分片 (客戶端自動)

Memcached 客戶端內建一致性哈希 (Ketama 算法),添加多台 Server 即可自動分片:

$mem = new Memcached();
$mem->addServer('10.0.0.1', 11211, 33); // 權重 33
$mem->addServer('10.0.0.2', 11211, 33);
$mem->addServer('10.0.0.3', 11211, 34);
  • 鍵自動路由到對應節點
  • 節點增減只影響少量鍵重新分佈
  • 業務層無感知

業務鍵設計規範

// 格式: {業務域}:{實體類型}:{ID}:{屬性}
// 示例:
$userProfile = "user:profile:10001";           // 用戶基本信息
$userSession = "user:session:s_abc123";        // Session
$productInfo = "product:info:SKU_20240101";    // 商品詳情
$categoryTree = "category:tree:level1";        // 分類樹
$rateLimit = "ratelimit:ip:192.168.1.1";       // 限流計數器
  • 使用冒號分隔,便於正則匹配、手動清理
  • 統一前綴區分環境:prod:... / dev:...
  • 避免過長鍵 (>250 字節),影響性能

緩存穿透/雪崩/擊穿解決方案

問題現象Memcached 方案
緩存穿透查詢不存在的 Key,每次直穿 DB緩存空對象 (set key '' 300s) + 布隆過濾器預檢
緩存雪崩大量 Key 同期過期,請求洪峰打 DBTTL 加隨機值 (300+rand(0,60)) + 多級緩存 (本地 APCu + Memcached)
緩存擊穿熱點 Key 失效瞬間大量併發重建互斥鎖重建 (Memcached add 鎖) 或 永不過期 + 異步更新

互斥鎖重建熱點 Key 示例

<?php
function getWithLock($key, $ttl, callable $rebuilder) {
    global $mem;
    $val = $mem->get($key);
    if ($val !== false) return $val;

    // 嘗試獲取鎖 (add 只有鍵不存在才成功)
    $lockKey = "lock:$key";
    if ($mem->add($lockKey, 1, 10)) { // 鎖過期 10s 防死鎖
        try {
            $val = $rebuilder(); // 重建數據 (查 DB、計算等)
            $mem->set($key, $val, $ttl);
        } finally {
            $mem->delete($lockKey);
        }
        return $val;
    } else {
        // 等待持有鎖的進程重建完成
        usleep(50000); // 50ms
        return getWithLock($key, $ttl, $rebuilder); // 遞歸重試
    }
}

// 使用
$hotData = getWithLock('homepage:banner', 3600, function() {
    return $db->query("SELECT * FROM banner WHERE status=1 ORDER BY sort");
});
?>

安全加固

1. 內網隔離 (最關鍵)

  • Memcached **無認證機制**,任何能連接端口的客戶端都可讀寫數據
  • **必須**部署在內網,綁定內網 IP:memcached -l 10.0.0.1 -p 11211
  • Web 服務器通過內網 IP 訪問,禁止公網暴露

2. 防火牆限制訪問來源

# iptables 示例:只允許 Web 服務器集群訪問
iptables -A INPUT -p tcp -s 10.0.1.0/24 --dport 11211 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.2.0/24 --dport 11211 -j ACCEPT
iptables -A INPUT -p tcp --dport 11211 -j DROP

3. 禁用 UDP (如不需要)

memcached -U 0  # 關閉 UDP 端口,僅保留 TCP

4. 監控關鍵指標

$stats = $mem->getStats();
$serverStat = $mem->getServerStatus('10.0.0.1', 11211);
print_r($stats);
/*
關注指標:
- curr_items: 當前項目數
- bytes: 佔用內存
- limit_maxbytes: 最大內存
- get_hits / get_misses: 命中率 = hits/(hits+misses)
- evictions: 驅逐次數 (內存不足被動刪除)
- curr_connections: 當前連接數
*/
?>

性能調優參數 (啟動參數)

memcached -d -m 2048 -u memcached -l 10.0.0.1 -p 11211 -c 4096 -t 4 -R 20 -B binary
# -m 2048: 最大內存 2GB
# -u memcached: 運行用戶 (非 root)
# -c 4096: 最大並發連接
# -t 4: 工作線程數 (CPU 核心數)
# -R 20: 最大請求處理速率限制 (每事件循環)
# -B binary: 二進制協議 (更高效)

遷移建議:Redis 作為更強替代者

場景選 Memcached選 Redis
純緩存、Key-String、超大內存、極高 QPS✅ 更輕量、多線程、內存利用率高單線程可能成瓶頸
需要持久化、複雜數據結構、發布訂閲、Lua 腳本❌✅ 原生支持
Session 共享、分布式鎖、排行榜、延遲隊列❌ 難以實現✅ 一行代碼
現有架構已深度綁定 Memcached✅ 維護成本低遷移成本高

新項目**首選 Redis**,老項目 Memcached 運行穩定則無需強行遷移。

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