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

PHP Memcache 基本操作完整實戰範例

     編輯:PHP 綜合知識

前言

Memcache 是高效能分散式記憶體快取系統,PHP Memcache 擴展提供物件導向介面。本文涵蓋連線、增刪改查、統計資訊、進階模式(快取穿透/擊穿/雪崩防護)完整實戰範例。

一、基礎操作範例

<?php
// 基本連線與操作
$mem = new Memcache();
$mem->connect('127.0.0.1', 11211) or die("連線失敗");

// 1. 新增(不存在才寫入)
$mem->add('user:1:name', 'Alice', 0, 3600);  // key, value, flag, expire(秒)
$mem->add('user:1:age', 25, 0, 3600);

// 2. 設定(覆蓋寫入)
$mem->set('user:1:city', 'Taipei', 0, 3600);

// 3. 取得單一
$name = $mem->get('user:1:name');
echo "Name: $name\n";

// 4. 批次取得
$keys = ['user:1:name', 'user:1:age', 'user:1:city'];
$vals = $mem->get($keys);
print_r($vals);  // ['user:1:name'=>'Alice', 'user:1:age'=>25, ...]

// 5. 替換(存在才更新)
$mem->replace('user:1:name', 'Alice Chen', 0, 3600);

// 6. 刪除
$mem->delete('user:1:age');

// 7. 統計資訊
print_r($mem->getStats());        // 伺服器統計
print_r($mem->getExtendedStats()); // 詳細統計(含 slab 資訊)

$mem->close();
?>

二、實戰模式:快取穿透/擊穿/雪崩防護

場景:查詢城市 PM2.5 資料

<?php
// pm25_cache.php
$mem = new Memcache();
$mem->connect('127.0.0.1', 11211);

$city = $_GET['city'] ?? 'Taipei';
$cacheKey = "pm25:$city";
$expire = 300;  // 5 分鐘

// 1. 嘗試從快取取得
$cached = $mem->get($cacheKey);
if ($cached !== false) {
    echo json_encode(['source' => 'cache', 'data' => $cached]);
    exit;
}

// 2. 快取未命中 → 查資料庫
// 模擬 DB 查詢
$dbData = queryPm25FromDb($city);  // 你的 DB 查詢函式

if ($dbData) {
    // 3. 寫入快取(防止快取穿透:即使查無資料也快取空值,短期)
    $mem->set($cacheKey, $dbData, 0, $expire);
    echo json_encode(['source' => 'db', 'data' => $dbData]);
} else {
    // 查無資料:快取空陣列 1 分鐘,防止穿透
    $mem->set($cacheKey, [], 0, 60);
    echo json_encode(['source' => 'db', 'data' => []]);
}

function queryPm25FromDb($city) {
    // 實際對接 PDO/MySQLi
    // return $pdo->query("SELECT * FROM pm25 WHERE city='$city'")->fetch();
    return ['city' => $city, 'pm25' => rand(10, 150), 'time' => date('H:i:s')];
}
?>

進階:防快取擊穿(熱點 Key 同時過期大量請求打 DB)

<?php
function getWithMutex($mem, $key, $expire, $dbCallback) {
    $value = $mem->get($key);
    if ($value !== false) return $value;
    
    // 取得分散式鎖(利用 add 原子性)
    $lockKey = "$key:lock";
    $lockExpire = 10;  // 鎖最多持有 10 秒
    
    if ($mem->add($lockKey, 1, 0, $lockExpire)) {
        // 獲得鎖:查 DB 並寫入快取
        $value = $dbCallback();
        $mem->set($key, $value, 0, $expire);
        $mem->delete($lockKey);  // 釋放鎖
        return $value;
    } else {
        // 未獲鎖:短暫睡眠重試(或直接回傳舊資料)
        usleep(50000);  // 50ms
        return $mem->get($key) ?: $dbCallback();  // 兜底
    }
}

// 使用
$data = getWithMutex($mem, "hot:key", 300, function() {
    return queryDb();
});
?>

防快取雪崩(大量 Key 同時過期)

  • 過期時間加隨機值: $expire = 300 + rand(0, 60) 錯開過期時間。
  • 多級快取: 本地記憶體(APCu/靜態變數)+ 分散式 Memcache/Redis。
  • 預熱機制: 部署後、低峰期主動重建熱點快取。

三、Memcache vs Memcached 擴展選擇

特性Memcache (舊)Memcached (新,推薦)
類別名MemcacheMemcached
支援二進位協議否是
支援 SASL 認證否是
支援觸發回呼否是
效能一般較好
維護狀態低活躍

建議: 新專案一律使用 Memcached 擴展,API 相似但功能更完整。

四、常見坑與避雷指南

  • Key 長度限制: 250 字元,超長需自行哈希(如 md5($longKey))。
  • Value 大小限制: 預設 1MB,大物件需壓縮 gzcompress() 或拆分。
  • Flag 參數: 自定義標記(如壓縮標記),get 時會回傳,應用層自行處理。
  • 連線重用: 使用持久連線 $mem->pconnect() 或連線池,避免頻繁建立 TCP 連線。
  • 序列化: 複雜陣列/物件自動序列化,注意版本相容性,跨語言建議用 JSON/MessagePack。

五、監控關鍵指標

$stats = $mem->getStats();
echo "命中率: " . ($stats['get_hits'] / ($stats['get_hits'] + $stats['get_misses']) * 100) . "%\n";
echo "記憶體使用: " . ($stats['bytes'] / 1024 / 1024) . " MB\n";
echo "連線數: " . $stats['curr_connections'] . "\n";
echo "項目數: " . $stats['curr_items'] . "\n";

小結

Memcache 核心操作極簡單:add/set/get/delete/replace。實戰關鍵在於 快取策略設計:合理設定過期時間、防穿透/擊穿/雪崩、監控命中率。新專案請改用 Memcached 擴展 或 Redis(功能更豐富、支援資料結構、持久化),Memcache 適合純 Key-Value、極高讀寫、無持久化需求的場景。

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