1. 程式人生 > >Netflix資料庫架構變革:縮放時間序列的資料儲存

Netflix資料庫架構變革:縮放時間序列的資料儲存

640?wx_fmt=jpeg


Netflix分析了其資料集的訪問模式,對檢視資料儲存架構進行了重新設計,並採用群集分片的資料分類方式,實時和壓縮資料並行的讀取模式。以尋求滿足更多的獨特需求與成本,效率的改進。本文來自Netflix技術部落格,LiveVideoStack對文章進行了翻譯。


文/ Dhruv Garg, Dhaval Patel, Ketan Duvedi

譯/ 元寶

審校/ 

原文 https://medium.com/netflix-techblog/scaling-time-series-data-storage-part-ii-d67939655586


2016年1月,Netflix在全球範圍內擴充套件,向130個國家開放服務,支援20種語言。2016年晚些時候,電視體驗逐漸演變為在瀏覽體驗期間包含視訊預覽。更多的成員,更多的語言和更多的視訊播放將時間序列資料儲存架構從第一部分(https://medium.com/netflix-techblog/scaling-time-series-data-storage-part-i-ec2b6d44ba39)延伸至其突破點。在本文的第二部分中,我們將探討該架構的侷限性,並描述如何在演化的下一階段重新構建。


突破點


第一部分的架構將所有觀看資料視為相同,無論型別(完整標題播放與視訊預覽)或年齡(標題的檢視時間)。隨著該功能推廣到更多裝置,預覽與完整檢視的比例迅速增長。到2016年底,我們看到該資料儲存在一個季度內增長了30%; 由於對該資料儲存的潛在影響,視訊預覽的推出被推遲。簡單的解決方案是擴充套件底層的檢視資料Cassandra(C *)叢集以適應這種增長,但它已經是使用中最大的叢集,並且接近叢集大小限制,很少有C *使用者成功通過。必須要做點什麼,但那太早了。


重新思考我們的設計


我們挑戰自己,重新思考我們的方法,並設計出一種至少能實現5倍增長的方法。我們有可以從第一部分的架構中重用的模式,但只有這些模式本身是不夠的,還需要新的模式和技術。


分析


我們首先分析了資料集的訪問模式,得到三種不同的資料類別:


完整標題播放

視訊預覽播放

語言偏好(即播放了哪些字幕/配音,表示成員在播放給定語言的字幕時的偏好是什麼)


對於每個類別,我們發現了另一種模式——大多數訪問都是針對最近的資料。隨著資料年齡的增長,所需的詳細程度降低。將這些見解和我們與資料消費者的對話結合起來,我們討論了哪些資料需要詳細資訊以及持續多長時間。


儲存效率低下


對於增長最快的資料集,視訊預覽和語言資訊,我們的合作伙伴只需要最近的資料。我們的合作伙伴正在過濾非常短暫的視訊預覽檢視,因為它們不是會員對內容意圖的正面或負面訊號。此外,我們發現大多數會員為他們觀看的大多數標題選擇相同的subs / dubs語言。在每個檢視記錄中儲存相同的語言首選項會導致大量資料重複。


客戶端複雜性


我們研究的另一個限制因素是檢視資料服務的客戶端庫如何滿足呼叫者對特定時間段內特定資料的特殊需求。呼叫者可以通過指定來檢索檢視資料:


視訊型別——完整標題或視訊預覽

時間範圍——最後X天/月/年,X對於各種用例不同

詳細程度——完整或摘要

是否包含subs / dubs資訊


對於大多數用例,在從後端服務獲取完整資料後,這些過濾器應用於客戶端。正如您可能想象的那樣,這導致了大量不必要的資料傳輸。此外,對於較大的觀看資料集,效能會迅速下降,導致第99個百分點的讀取延遲發生巨大變化。


重新設計


我們的目標是設計一個可以擴充套件到5倍增長的解決方案,具有合理的成本效率和改進以及更容易預測的延遲。通過對上述問題的分析和理解,我們進行了這次重大的重新設計。以下是我們的設計指南:


資料類別


按資料型別分片

將資料欄位簡化為基本元素


資料時代


按資料年齡劃分的碎片。對於最近的資料,在設定TTL後過期

對於歷史資料,彙總並旋轉到歸檔群集中


效能


並行化讀取以提供跨最近和歷史資料的統一抽象


群集分片


以前,我們將所有資料合併到一個叢集中,客戶端庫根據型別/年齡/詳細程度過濾資料。我們顛倒了這種方法,現在根據型別/年齡/細節水平對聚類進行分片。這樣可以將每個資料集的不同增長率彼此分離,簡化了客戶端,並改善了讀取延遲。


儲存效率


對於增長最快的資料集、視訊預覽和語言資訊,我們能夠與合作伙伴保持一致,僅保留最新的資料。我們不會儲存非常短暫的預覽視訊,因為它們不是會員對內容感興趣的良好訊號。此外,我們現在儲存初始語言首選項,然後僅儲存後續播放的增量。對於絕大多數會員而言,這意味著只儲存一條語言偏好記錄,從而節省大量儲存空間。對於預覽播放和語言偏好資料,我們也有較低的TTL,因此比完整標題播放的資料更容易過期。


如果需要,我們應用第一部分中的實時和壓縮技術,其中可配置數量的最近記錄以未壓縮的形式儲存,其餘記錄以壓縮形式儲存在單獨的表中。對於儲存較舊資料的叢集,我們將資料完全以壓縮形式儲存,在訪問時以較低的儲存成本換取較高的計算成本。


最後,我們不是儲存歷史完整標題播放的所有細節,而是在單獨的表中儲存具有較少列的彙總檢視。此摘要檢視也經過壓縮,可進一步優化儲存成本。

總的來說,我們的新架構如下所示:


640?wx_fmt=png


檢視資料儲存架構


如上所示,檢視資料儲存是按型別分片的——有完整標題播放、預覽標題播放和語言首選項的單獨叢集。在完整的標題播放中,儲存按年齡分類。對於最近檢視資料(最近幾天)、過去檢視資料(幾天到幾年)和歷史檢視資料都有單獨的叢集。最後,歷史檢視資料只有一個摘要檢視,沒有詳細的記錄


640?wx_fmt=png


資料流


寫入


將資料寫入到最近的叢集中。在輸入之前應用過濾器,例如不儲存非常短的視訊預覽播放或將播放的字幕/配音與以前的首選項進行比較,並且僅在與先前行為發生變化時儲存。


讀取


對最新資料的請求直接轉到最新的叢集。當請求更多資料時,並行讀取可以實現高效檢索。


檢視資料的最後幾天:對於絕大多數需要幾天完整標題播放的用例,資訊僅從“最近”叢集中讀取。執行對叢集中LIVE和COMPRESSED表的並行讀取。繼續本博文系列第一部分詳細介紹的實時和壓縮資料集的模式,如果記錄數超出可配置的閾值,則在從LIVE讀取期間,將記錄彙總,壓縮並寫入COMPRESSED表作為具有相同行鍵的新版本。


另外,如果需要語言偏好資訊,則對“語言偏好”叢集進行並行讀取。同樣,如果需要預覽播放資訊,則會對“預覽標題”叢集中的LIVE和COMPRESSED表進行並行讀取。與完整標題檢視資料類似,如果LIVE表中的記錄數超過可配置閾值,則記錄將被彙總,壓縮並作為具有相同行鍵的新版本寫入COMPRESSED表。


通過對“最近”和“過去”群集的並行讀取,可以啟用最近幾個月的完整標題播放。


彙總的檢視資料通過並行讀取 “最近”,“過去”和“歷史”叢集返回。然後將資料拼接在一起以獲得完整的彙總檢視。為了減少儲存大小和成本,“歷史”叢集中的彙總檢視不包含成員檢視的最後幾年的更新,因此需要通過彙總來自“最近”和“過去”叢集的檢視資料來進行擴充。


資料輪換


對於完整的標題播放,不同年齡組之間的記錄移動是非同步發生的。在從“最近”叢集中讀取會員的檢視資料時,如果確定存在超過配置天數的記錄,則任務排隊以將該會員的相關記錄從“最近”移動到“過去”叢集。在任務執行時,相關記錄與“過去”叢集中COMPRESSED表的現有記錄組合在一起。然後壓縮組合的記錄集並將其儲存在具有新版本的COMPRESSED表中。新版本寫入成功後,將刪除先前的版本記錄。


如果壓縮後的新版本記錄集的大小大於可配置的閾值,則將記錄集分塊並且多個塊被並行寫入。這些記錄從一個叢集到另一個叢集的後臺傳輸是批處理的,因此每次讀取時都不會觸發它們。所有這些都類似於第一部分中詳述的實時壓縮儲存方法中的資料移動。


640?wx_fmt=png


群集之間的資料輪換


類似的記錄到“歷史”叢集的移動是在讀取“過去”叢集時完成的。使用現有摘要記錄重新處理相關記錄以建立新的摘要記錄。然後將它們壓縮並寫入具有新版本的“歷史”叢集中的COMPRESSED表。成功寫入新版本後,將刪除以前的版本記錄。


效能調優


與之前的體系結構一樣,LIVE和COMPRESSED記錄儲存在不同的表中,並進行不同的調整以獲得更好的效能。由於LIVE表具有頻繁的更新和少量的檢視記錄,因此壓縮會頻繁執行,並且gc_grace_seconds很小,以減少SSTable的數量和資料大小。經常執行讀取修復和全列族修復以提高資料一致性。由於對COMPRESSED表的更新很少,因此手動和不頻繁的完全壓縮足以減少SSTable的數量。在罕見的更新期間檢查資料的一致性。這樣就不需要進行讀取修復以及全列修復。


快取層更改


由於我們對來自Cassandra的大資料塊進行了大量並行讀取,因此擁有快取層有很大的好處。EVCache快取層架構也進行了更改,以模擬後端儲存架構,如下圖所示。所有快取都有接近99%的命中率,並且在最小化對Cassandra層的讀取請求數量方面非常有效。

 


快取層架構


快取和儲存體系結構之間的一個區別是“摘要”快取叢集儲存整個檢視資料的壓縮摘要以進行完整標題播放。快取命中率約為99%,只有一小部分請求被髮送到Cassandra層,在該層中,需要並行讀取3個表,並將記錄拼接在一起,以便跨整個檢視資料建立摘要。


遷移:初步結果


團隊已經完成了一半以上的更改。已經遷移了利用按資料型別分片的用例。因此,雖然我們沒有完整的結果可以分享,但初步的結果和經驗教訓如下:


Cassandra的操作特性(壓縮,GC壓力和延遲)的大幅改進僅基於按資料型別分割群集。

完整標題的巨大空間,檢視資料Cassandra叢集,使團隊能夠擴充套件至少5倍的增長。

由於更積極的資料壓縮和資料TTL,大幅節省了成本。

重新架構是向後相容的。現有的API將繼續有效工作,並且預計會有更好和更可預測的延遲。為訪問資料子集而建立的新API將帶來顯著的額外延遲優勢,但需要更改客戶端。這使得在獨立於客戶端更改的情況下推出伺服器端更改變得更加容易,並且可以根據客戶端的業務頻寬在不同的時間遷移不同的客戶端。


結論


在過去幾年中,檢視資料儲存架構已經取得了很大的進步。我們逐步發展到使用實時資料和壓縮資料並行讀取的模式來檢視資料儲存,並將該模式用於團隊中的其它時間序列資料儲存需求。最近,我們對儲存叢集進行了分片,以滿足不同用例的獨特需求,併為一些叢集使用了實時和壓縮資料模式。我們擴充套件了實時和壓縮資料移動模式,以便在年齡分片群集之間移動資料。


設計這些可擴充套件的構建塊以一種簡單而有效的方式擴充套件我們的儲存層。雖然我們重新設計了5倍於當前用例增長的產品,但我們知道Netflix的產品體驗在不斷變化和改進。我們也正密切關注可能需要進一步進化的變化。


精品文章推薦






技術乾貨:



人物專訪: