Memcache mutex設計模式

週六的S2 Web 2.0技術沙龍上介紹了memcache中使用mutex場景(文後要演講稿),有網友對詳情感興趣,簡單介紹以下。php

場景

Mutex主要用於有大量併發訪問並存在cache過時的場合,如html

  • 首頁top 10, 由數據庫加載到memcache緩存n分鐘
  • 微博中名人的content cache, 一旦不存在會大量請求不能命中並加載數據庫
  • 須要執行多個IO操做生成的數據存在cache中, 好比查詢db屢次

問題

在大併發的場合,當cache失效時,大量併發同時取不到cache,會同一瞬間去訪問db並回設cache,可能會給系統帶來潛在的超負荷風險。咱們曾經在線上系統出現過相似故障數據庫

解決方法

方法一
在load db以前先add一個mutex key, mutex key add成功以後再去作加載db, 若是add失敗則sleep以後重試讀取原cache數據。爲了防止死鎖,mutex key也須要設置過時時間。僞代碼以下
(注:下文僞代碼僅供瞭解思路,可能存在bug,歡迎隨時指出。)緩存

if (memcache.get(key) == null) {
    // 3 min timeout to avoid mutex holder crash
    if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
        value = db.get(key);
        memcache.set(key, value);
        memcache.delete(key_mutex);
    } else {
        sleep(50);
        retry();
    }
}

方法二
在value內部設置1個超時值(timeout1), timeout1比實際的memcache timeout(timeout2)小。當從cache讀取到timeout1發現它已通過期時候,立刻延長timeout1並從新設置到cache。而後再從數據庫加載數據並設置到cache中。僞代碼以下併發

v = memcache.get(key);
if (v == null) {
    if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
        value = db.get(key);
        memcache.set(key, value);
        memcache.delete(key_mutex);
    } else {
        sleep(50);
        retry();
    }
} else {
    if (v.timeout <= now()) {
        if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
            // extend the timeout for other threads
            v.timeout += 3 * 60 * 1000;
            memcache.set(key, v, KEY_TIMEOUT * 2);

            // load the latest value from db
            v = db.get(key);
            v.timeout = KEY_TIMEOUT;
            memcache.set(key, value, KEY_TIMEOUT * 2);
            memcache.delete(key_mutex);
        } else {
            sleep(50);
            retry();
        }
    }
}

相對於方案一
優勢:避免cache失效時刻大量請求獲取不到mutex並進行sleep
缺點:代碼複雜性增大,所以通常場合用方案一也已經足夠。app

方案二在Memcached FAQ中也有詳細介紹 How to prevent clobbering updates, stampeding requests,而且Brad還介紹了用他另一個得意的工具 Gearman 來實現單實例設置cache的方法,見 Cache miss stampedes,不過用Gearman來解決就感受就有點奇技淫巧了。less

附:本次Web2.0技術沙龍演講主題:微博Cache設計談,需下載請點擊演講稿下menu/download (需登陸slideshare)。ide

相關文章
相關標籤/搜索