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

PHP Memcached 批量獲取保持鍵順序:GET_PRESERVE_ORDER 參數實戰

     編輯:PHP 綜合知識

問題背景

Memcached::getMulti() 預設返回關聯陣列,順序不保證(取決於內部哈希分佈)。多節點時,返回順序與請求鍵順序不一致,導致業務邏輯難以對應。

解決方案:GET_PRESERVE_ORDER

<?php
$md = new Memcached();
$md->addServers([['10.0.0.1', 11211], ['10.0.0.2', 11211]]);

// 啟用一致性哈希(前提)
$md->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$md->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);

$keys = [
    'line_31639', 'line_33878', 'line_177410', 'line_9735', 'line_589',
    'line_12076', 'line_25953', 'line_22447', 'line_15368', 'line_15358',
    'line_33853', 'line_26658', 'line_26659', 'line_12477', 'line_15366'
];

// 關鍵:第三參數傳入常量
$cas = null;
$results = $md->getMulti($keys, $cas, Memcached::GET_PRESERVE_ORDER);

// $results 陣列順序與 $keys 完全一致
// 未命中鍵值為 false,$cas 陣列同序對應 CAS token
foreach ($keys as $i => $key) {
    if ($results[$i] === false) {
        echo "Miss: $key\n";
    } else {
        echo "Hit: $key = {$results[$i]}\n";
    }
}
?>

處理未命中鍵:二次查詢/回填

<?php
// 找出未命中鍵
$missedKeys = [];
foreach ($keys as $i => $key) {
    if ($results[$i] === false) $missedKeys[] = $key;
}

if ($missedKeys) {
    // 從資料庫/上游獲取
    $fetched = fetchFromDb($missedKeys); // 返回關聯陣列 [key=>val]
    
    // 回填 Memcached
    $md->setMulti($fetched, 3600);
    
    // 合併結果
    foreach ($missedKeys as $key) {
        $idx = array_search($key, $keys);
        $results[$idx] = $fetched[$key];
    }
}

// 現在 $results 完整且順序正確
processResults($results);
?>

原理說明

  • GET_PRESERVE_ORDER 內部實現:客戶端按鍵順序發送請求、接收響應,而非並行管線化。略微增加延遲(串行 vs 並行),但保證順序。
  • 單節點時預設即有序(單連線管線化),多節點時必須顯式開啟。
  • $cas 參數同序返回各鍵 CAS token,配合 cas() 實現批量樂觀鎖更新。

效能權衡

順序保證犧牲部分並行度。若鍵數量大(>100),考慮分批並行獲取,或接受無序並在應用層排序(array_replace、array_intersect_key)。

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