1. 程式人生 > >論文筆記:Scaling Memcache at Facebook

論文筆記:Scaling Memcache at Facebook

論文筆記:Scaling Memcache at Facebook

論文介紹了Facebook如何使用memcache,以及相關魔改和維護memcache叢集。

歡迎訪問我的部落格

背景

facebook使用一致性雜湊來構建memcahce叢集。

We provision hundreds of memcached servers in a cluster to reduce load on databases and other services.
Items are distributed across the memcached servers through consistent hashing [22]. 
Thus web servers have to routinely communicate with many memcached servers to satisfy a user request

使用

cache aside模式

facebook根據他們的場景,也就是讀多寫少使用了cache aside模式。原文叫demand-filled look-aside cache。具體使用方式如下圖。

facebook 使用delete而不是update快取的原因是因為delete是冪等的,而update不是(we choose to delete cached data instead of updating it because deletes are idempotent).如果直接更新可能出現先更新的後放入快取。

在facebook也是用memcache作為大資料平臺計算的中間結果儲存平臺,用來存放一些中間結果

魔改

魔改背景

一個web請求會請求平均521個獨立的快取項.(A single user web request can often result in hundreds of individual memcache get requests. For example, loading one of our popular pages results in an average of 521 distinct items fetched from memcache)

魔改目的

魔改的目的是為了降低延遲,降低負載。

魔改方法

延遲與負載:1.網路延遲 2.由於cache miss帶來的延遲和後端的負載。解決方案如下:

  1. 程式碼批量化訪問快取,減少來回的網路開銷
  2. 對於網路延遲的降低,facebook對於GET使用UDP傳輸,SET和DELETE使用TCP傳輸。因為UDP是無連線的,可以降低TCP維護連結的開銷。使用UDP客戶端自己記錄請求序號,丟包和亂序被視為客戶端錯誤,在實際生產環境中,有0.25%的get請求被扔掉。其中的80%是因為回包延遲,其他的是因為亂序。對於上面的錯誤,客戶端直接認為是cache miss。直接取後端,但是不會放入快取是為了避免額外的網路開銷
    效果如下圖:
  3. 使用類似TCP擁塞控制的方法來防止快取叢集負載過高。客戶端維護一個滑動視窗,當服務端正常響應,就加大視窗,當服務端沒響應或者超時就減小視窗。

後端負載降低

1.引入“租約Leases”,租約用來解決兩個方面的問題 1. 過期的設定 2.驚群效應(stale sets and thundering herds)。

  • 過期的設定主要來源於放入快取的順序錯亂(後來先到)。
  • 驚群效應發生在某個key被頻繁的讀寫。由於寫是invalid cache,所以大量讀請求就會無法命中快取,導致進入了後端的資料庫。
  • 租約就是一個對應於請求的key的64bit的token。(The lease is a 64-bit token bound to the specific key the client originally requested)。當set cache的時候,客戶端需要把這個key帶上一起給到快取伺服器,當服務端發現token不匹配的時候,就說明這是一個過期的寫請求。
  • 租約同時可以降低驚群效應。快取伺服器控制發token的頻率,預設是10秒一次,快取伺服器發過一次token後,後續再來的請求就直接等一會(等前面那個拿到token的返回之後,快取就有資料了)
    Without leases, all of the cache misses resulted in a peak database query rate of 17K/s. With leases, the peak database query rate was 1.3K/s

2.使用過期值

  • 通過返回slightly out-of-date data,當一個key被刪除的時候,在真正flush之前,會被放入一個特殊的資料結構中。get請求可以返回一個租約或者這個被標記為過期的值。

3.處理失敗,這裡的失敗有兩種

  • 有一小部分機器由於網路原因無法訪問(facebook依賴一個自動化的元件去發現這些機器,但需要時間 few minutes,在這一段時間內可能會帶來一些連鎖失敗)
    解決辦法:有一個叫gutter的小池子,大概是cache叢集的1%大小,用來替代那些無法訪問的機器。當client無法收到快取伺服器的響應,他們就去訪問gutter池子裡面的機器。注意這根一般一致性雜湊的玩法不一樣,原因是有可能有些key非常的熱,如果把它hash到下一臺機器,就會增加那臺機器的負載,導致又爆炸。把它導到空閒的gutter機器上就可以避免這個問題。一旦出現一臺快取機器無法訪問,gutter通常能在4分鐘內,快取命中率能超過35%,有時能達到50%
  • 叢集中的大部分機器都無法訪問
    解決辦法:切換流量到其他可用region

維護memcache叢集

待續