天天看點

[地鐵譯]使用SSD緩存應用資料——Moneta項目: 低成本優化的下一代EVCache目前的架構Moneta 架構結論

閱讀國外的技術部落格和技術網站是跟随時代腳步的重要方式,Netflex 有自己的開源門戶OSS,更是微服務架構的推崇者,擁有自己的微服務架構技術站,其技術部落格中有不少幹貨,于是在地鐵閱讀時光裡便有了這篇譯文。

原文自:

http://techblog.netflix.com/2016/05/application-data-caching-using-ssds.html

随着Netflix的全球化擴張,也帶來了資料的急劇膨脹。在Active-Active 項目和現在的N+1架構之後, 最新的個性化推薦資料遍布各地,在任何時間服務于所有地區的任何人。緩存作為使用者個性化推薦資料的駐留層扮演着一個非常關鍵的角色。

在Netflix架構中有兩個基本元素,一個是控制平面,運作在AWS之上,用于使用者登入,浏覽和播放以及一般性服務。另一個是資料平面,叫做Open Connect, 這是一個全球性的視訊分發網絡。本文介紹了如何在EVCache中利用經濟的SSD能力,EVCache是Netflix中所使用的基本緩存系統,它運作在AWS的控制平面。

使用EVCache的一個典型用例是對個性化資料作全局的副本存儲,服務于8100萬Netflix使用者。EVCache 在Netflex内部扮演着不同的角色,處理儲存使用者的個性化推薦資料,還包括作為标準的緩存工作集來存儲使用者的資訊。但是最大的角色還是個性化推薦。為任何地區的任何人服務意味着,我們必須為已營運的三個地區的每個人持有使用者的個性化推薦資料。這保證了所有AWS 可用區的一緻性體驗,同時便于切換區域間的流量來平衡負載。

http://techblog.netflix.com/2016/03/caching-for-global-netflix.html

已經介紹了全球化的副本系統。

在穩定狀态,在Netflex的區域内可以反複地看到同一個使用者,區域切換對使用者而言并不是常态。盡管資料在三個區域的記憶體中,隻有一個區域中的每個使用者正常使用。由此推斷,在每個區域有着這些緩存的不同工作集,一個小的子集是熱資料,其他是冷資料。

除了冷熱資料的分類之外,所有在記憶體中的這些資料存儲成本随着使用者的基數在增加。 另外, 不同的 A/B 測試和其他的内部改變增加了更多的資料。對于使用者的工作集,Netflix已經有了數十億的主鍵,而且數目還在增長。面對的挑戰是持續支撐Netflix業務并平衡成本,進而引入了多級緩存機制,即同時使用 RAM 和SSD。

基于EVCache 充分利用這種全局化請求釋出和成本優化的項目叫做 Moneta, 源自拉丁記憶女神的名字,也是羅馬神話中财富守護神——Juno Moneta。

目前的架構

先看一下 EVCache 伺服器的目前架構,然後讨論如何演變成對SSD 的支援。

下圖展示了EVCache 的典型部署結構和單節點用戶端執行個體于伺服器的關系。一個EVCache用戶端連接配接了多個EVCache的伺服器叢集。 在一個區域内,Netflix有多個全資料集的拷貝,由AWS的可用區隔離開來。虛線框描述了區域内的副本,每個擁有資料的全量拷貝作為一個單元,作為隔離AWS的自動伸縮組來管理這些拷貝。某些緩存在一個區域内有兩個拷貝,有的擁有更多。這種高層架構對我們長期來看還是有效的,不會改變。每個客戶的連接配接自己區域内所有可用區的所有伺服器。寫操作被發往所有的拷貝,讀操作優先選擇離讀請求近的伺服器。關于EVCache 架構的更多細節,參見最初的

博文

在過去的幾年中,這一伺服器已經包含了一組程序,兩個主要的程序是: Memcached, 一個流行的且久經考驗的記憶體型鍵值對存儲,和 Prana, 這是一個 Netflix sidecar 程序。 Prana 是連接配接Netflix 生态系統中其他服務的伺服器,也是基于Java開發的。用戶端直接連接配接運作在每個server上的Memcached程序。伺服器是獨立的,互相之間不通信。

優化

EVCache作為Netflix雲中最大的子系統之一,在系統優化中占有相當的比例,位置獨一無二。将所有資料存儲在記憶體的成本随着使用者基數的增長而上揚,單日個性化批處理輸出将加載超過5 T的資料到專用的 EVCache 叢集。 資料存儲成本是所存儲資料與全局副本個數的乘積。如前所述,不同的 A/B 測試和其他内部資料也增加了更多的資料。對于使用者的工作集,如今已經有數十億的鍵值,而且在持續增加。

根據不同區域不同的資料通路的情況,Netflix 建構了一個系統将熱資料存儲在RAM ,冷資料存儲在硬碟。這是典型的兩級緩存架構 ( L1 代表 RAM,L2 代表硬碟), Netflix的工程師依賴于EVCache的強一緻性和低延遲時間性能。面對盡量低的時延需求,要使用更多的昂貴記憶體,使用低成本的SSD也要滿足用戶端對低延遲時間的預期。

記憶體型 EVCache 叢集運作在 AWS r3系的執行個體類型上,對大規模記憶體的使用進行了優化。通過轉移到 i2 系的執行個體上,在相同的RAM和CPU的條件下,可以獲得比SSD存儲(r3 系)擴大十倍的增益 (80 → 800GB ,從 r3.xlarge 到 i2.xlarge) 。Netflix也降級了執行個體的大小到小型記憶體執行個體上。結合這兩點,就可以在數千台伺服器上作優先的成本優化了。.

Moneta 架構

Monte 項目在EVCahce 伺服器中引入了2個新的程序: Rend 和 Mnemonic。 Rend 是用Go語音寫的一個高性能代理,Mnemonic 是一個基于RocksDB的硬碟型鍵值對存儲。Mnemonic 重用了Rend 伺服器元件來處理協定解析 (如Memcached 協定), 連接配接管理和并行鎖。這三種伺服器都使用Memcached 的文本和二進制協定,是以用戶端與它們的互動有着相同的文法,給調試或者一緻性檢查帶來了便捷。

用戶端以前是直接與 Memcached 連接配接, 現在連接配接 Rend. 由此開始, Rend 将處理在 Memcached 和Mnemonic之間的 L1/L2 互動。甚至當伺服器不使用Mnemonic時, Rend 仍然提供了與原來使用Memcached時類似的伺服器性能,例如請求時延。Rend引入的時延,與Memcached 一起工作時,平均隻有幾十毫秒。

作為重新設計的一部分,已經将三個程序內建在一起了。三個獨立的程序運作在每個伺服器上比保持分離。這種配置更好地保證了資料的持久性, 一旦 Rend 挂了,資料還可以與 Memcached 和Mnemonic進行操作。一旦用戶端重新連接配接到Rend程序,伺服器就能夠服務使用者的請求了。 如果Memcached 挂了,将丢失所有的工作集資料,但L2中的資料(Mnemonic) 還是可用的。一旦資料被再次請求,将重新變為熱資料,和原來的服務一樣。 如果 Mnemonic挂了, 它并沒有丢失所有的資料,隻損失了最近寫入的資料。即使它丢失了資料,至少RAM中的熱資料還在,對使用服務的使用者還是可用的。This resiliency to crashes is on top of the resiliency measures in the EVCache client.

Rend

Rend, 如前所述, 作為另外兩個真正存儲資料的程序的代理,是一個高性能伺服器,使用二進制和文本Memcached 協定進行通信。它是Go語言寫的,依賴了其對并發處理的高性能。這個項目已經在 available on Github.上開源了。 決定使用Go時明智的,因為我們需要比Java更好的低延遲時間(這裡垃圾回收時的暫停是個問題),以及比C更好的生産效率,同時能處理成千上萬的用戶端連接配接,Go非常适合這樣的場景。

Rend 的職責是管理 L1 和 L2 緩存的關系,根據不同的内部使用場景采用不同的政策,還具有裁剪資料的特性,能夠将資料分割成固定的大小插入到Memcached中以避免記憶體配置設定時的pathological 行為。這種伺服器側的分片代替了用戶端分片,已經證明時可行的。至此,擁有了2倍讀和30倍寫的速度提升。幸運的是, Memcached 的1.4.25版本, 已經對用戶端異常引起的問題有了更多的健壯性處理。Netflex将來可能廢棄chunking的特性 feature in the future as we can depend on L2 to have the data if it is evicted from L1.

設計

Rend的設計是子產品化的,并且可配置。在内部,有這樣一些分層: 連接配接管理,伺服器循環,協定代碼,請求編排和背景處理器。使用Pranna的定制化包來避免輪詢資訊的侵入方式。 Rend 也有着獨立用來測試的用戶端代碼庫,能夠集中發行協定中的bug或者其他錯誤,例如錯誤對齊,未清除的緩存以及未完成的響應等。

Rend的設計允許不同背景的插件式嵌入,通過一個接口和一個構造函數即可。已經證明了這種設計的有效性,一個工程師在一天哪熟悉了相關代碼并學習了 LMDB,把它內建起來作為了存儲背景。這些代碼參見

https://github.com/Netflix/rend-lmdb

.

生産環境的使用

作為Moneta服務最好的那些緩存,一個伺服器就可以服務多種不同的用戶端。一類是熱路徑上的線上分析流量,使用者請求的個性化資料。其他是離線分析的流量和近限系統所産生的資料。這些典型的服務是整夜允許的巨量批處理和結束時幾個小時的持續寫操作。

子產品化允許使用預設的實作來優化Netflix夜間的批處理計算,直接在 L2 中插入資料并且在 L1中更換熱資料, 而不是在夜間預計算時引起L1緩存的寫風暴。來自其它區域的副本資料不像是熱資料,是以也直接插入 L2。下圖展示了一個 Rend 程序有多個端口連接配接了各種背景存儲。因為Rend的子產品化,很容易在不同的端口上引入其它的伺服器,幾行代碼就能實作批處理和流量副本。

性能

Rend 自身有着很高的吞吐量。獨立地測試 Rend,在CPU最大化前,看一下網絡帶寬和包處理的限制。 單個伺服器,請求不發往後端存儲,可以處理 286萬請求每秒。 這是原始資料,不是真正的數字。 隻使用Memcached作為後端存儲的話, Rend 可以承受22.5 萬每秒的插入操作, 20萬每秒的讀操作,在Netflix最大的執行個體上測試的結果。一個 i2.xlarge 執行個體被配置成 L1 和 L2 (記憶體和硬碟 ) 以及 data chunking, 這是Netflix 生産叢集的标準執行個體,能夠執行 22k插入每秒(隻是sets) 21k 讀操作每秒 (隻是 gets ), 并且是 10k sets 和 10k gets 每秒的并發。這些是生産環境的下限,因為測試資料包含了大量的随機鍵值進而避免了資料通路的局部性。真正的流量在L1中的命中率要比随機鍵值頻繁的多。

作為一個伺服器應用,Rend 打開了EVCache 伺服器智能化的各種可能性,也完全從協定到通信實作了基礎存儲的解耦合。 依賴于Netflix的需要,可以将L2存儲下架,将 L1 Memcached 配合上其他的存儲,或者改變伺服器的邏輯來增加全局鎖或者一緻性。這些是還沒計劃的項目,但是已經有定制化代碼運作在伺服器上了。

Mnemonic

Mnemonic 是基于RocksDB的L2 解決方案,在硬碟上存儲資料。協定解析,連接配接管理,Mnemonic 的并發控制等所有的管理都使用了和Rend 相同的庫。Mnemonic 是嵌入到Rend 伺服器的一個背景服務, Mnemonic項目暴露出一個定制化的C API 供Rend handler使用。

Mnemonic中有趣的部分是在 C++ 的核心層封裝了 RocksDB. Mnemonic 處理 Memcached風格的請求,實作了Memcached所有行為的所需操作,包括了 TTL 支援。它包含了一個重要的特性:将請求分發到一個本地系統的多個 RocksDB 資料庫,減少了每個RocksDB資料庫執行個體的負載。 下面解釋一下這麼做的理由。

RocksDB

在研究過有效通路 SSD的幾種技術之後,Netflix 選擇了RocksDB, 一個 嵌入式鍵值對存儲,它使用了日志結構合并樹的資料結構設計。寫操作首先插入到一個記憶體資料結構中(一個記憶體表),當滿的時候再寫入到硬碟上。當寫入硬碟的時候,記憶體表是一個不可修改的SST 檔案。這這樣形成了大量的序列化寫入SSD的操作,減少了大量的内部垃圾回收,改善了SSD在長時間運作的執行個體上的時延。

一種類型的負載已經由RocksDB的各個獨立執行個體在背景完成了。 Netflix開始使用了有層次的精簡配置,主要原因是在多個資料庫中分發請求。然而,當評估生産資料的精簡配置以及與生産環境類似的流量的時候,發現這樣的配置會引起大量額外的SSD讀寫,增加了時延。SSD 讀流量經常達到 200MB/sec。評估時的流量包括了長時間的高寫操作,仿真了每天的批處理計算程序。在此期間,RocksDB 持續的移動了新的 L0 記錄達到了一個很高的水準,放大為非常高的寫操作。

為了避免過載,Netflix切換到FIFO 型的精簡配置。在這種配置中,沒有真正的精簡操作被完成。基于資料庫的最大尺寸,删除舊的 Old SST 檔案。記錄在硬碟的 level 0中,是以隻在多個SST檔案中按時間排序。這種配置的下降趨勢在于讀操作必須在判斷一個鍵是否命中之前以時間倒序檢查每個SST檔案。這種檢查通常不需要硬碟讀操作, as the RocksDB的大量過濾器杜絕了高比例的對每個SST的硬碟通路。然而,SST檔案的數量影響了指派操作的有效性,将低于正常有層次風格的精簡操作。初始進入系統的讀寫請求在多個RocksDB的分發減少了掃描多個檔案的負面影響。

通過最終的配置重新運作測試,在預計算負載的期間,能夠得到99% 的讀請求時延在9ms左右。 在預計算負載完成後,對于相同水準,99% 的讀操作削減到 ~600μs。 所有這些測試都在沒有Memcached 和 RocksDB 塊緩存的情況下運作。

這種方案可以有更多的變種,可以減少SST 檔案的數量來減少查詢請求的需要。探索像 RocksDB的統一型精簡配置或者定制化精簡操作來更好的控制精簡比率進而降低與SSD之間的資料傳輸。

結論

Netflex 推出了生産環境的解決方案。 Rend 現在在生産環境中服務了一些最重要的個性化推薦資料集。數字表明了增加了穩定性并加快了操作的速度,減少了臨時的網絡問題。Netflix在早期的擴充卡上正在部署 Mnemonic (L2) 後端,同時在調優系統,結果看起來時有保證的,簡單易用并有效地降低了成本,保證了 EVCache 的一貫速度。

生産環境的部署是一個漫長旅程,還有很多事情要做:廣泛部署,監控,優化,重複清洗等。EVCache 伺服器的新架構可以用這樣的方法持續創新。