天天看點

Netflix 是如何實作每秒 200 萬次的資料處理?

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

Netflix 是如何實作每秒 200 萬次的資料處理,并查詢超過 1.5 萬億行的資料?

在推動技術創新更新的同時,還要確定 Netflix 始終如一的良好體驗,這并非易事。

如何才能確定更新不會影響到使用者呢?如果確定我們的改進是可度量的呢?Netflix 使用來自回放裝置的實時日志作為事件源來獲得度量,以便了解和量化使用者裝置浏覽和回放的流暢度。

Netflix 是如何實作每秒 200 萬次的資料處理?

一旦有了這些度量,我們就把它們輸入資料庫。每一項名額都附有與所使用裝置類型相關的匿名細節,例如,該裝置是智能電視、iPad 還是 Android 手機。這樣,我們就可以對裝置進行分類,并從不同的方面來檢視資料。同樣,我們還能夠隻隔離影響特定群體的問題,如應用的版本、特定類型的裝置或特定國家。

這些聚合資料可以立即用于查詢,可以通過儀表闆查詢,也可以通過即席查詢。這些名額還會持續檢查報警信号,比如新版本是否會影響某些使用者或裝置的回放或浏覽。這些檢查用于通知負責的團隊,讓他們可以盡快處理問題。

在軟體更新期間,我們為一部分使用者啟用新版本,并使用這些實時名額來比較新版本與舊版本的性能。在度量中,如果有任何不合适,我們可以中止更新并将那些已獲得新版本的使用者恢複到以前的版本。

由于這些資料的處理速度超過每秒 200 萬次,是以将其存入一個可以快速查詢的資料庫非常困難。我們需要足夠的資料維數,以便能夠有效地隔離問題,如此一來,我們每天生成超過 1150 億行資料。在 Netflix,我們利用 Apache Druid 幫助我們在這種規模下解決這一挑戰。

Druid

Apache Druid 是一個高性能的實時分析資料庫。它是針對特别注重快速查詢和攝取的工作流而設計。Druid 特别适合于即時的資料可視化、即席查詢、操作分析和高并發處理。——druid.io

是以,Druid 非常适合我們的用例,事件資料攝取率很高,而且具有高基數(high cardinality)和快速查詢需求。

Druid 不是一個關系型資料庫,但是一些概念是可以轉化的。我們有資料源,而不是表。與關系型資料庫一樣,有表示為列的資料邏輯分組。與關系型資料庫不同的是,沒有連接配接的概念。是以,我們需要確定在每個資料源中都包含希望的篩選或分組的列。

資料源中主要有三種列——時間、次元和度量。

Druid 中的一切都有時間标記。每個資料源都有一個時間戳列,這是主要的分區機制。次元是可用于篩選、查詢或分組的值。度量是可以聚合的值,并且幾乎總是數值。

通過移除執行連接配接的能力,并假設資料都有時間戳,Druid 可以在存儲、分發和查詢資料方面做一些優化,這樣我們就可以将資料源擴充到數萬億行,并且仍然可以實作查詢響應時間在 10 毫秒以内。

為了達到這種程度的可擴充性,Druid 把存儲的資料分成時間塊。時間塊的長度是可配置的。可以根據資料和用例選擇适當的區間。對于資料和用例,我們使用 1 小時的時間塊。時間塊中的資料存儲在一個或多個段中。每個段包含所有屬于這個時間塊的資料行,時間塊由它的時間戳列決定。段的大小可以配置為行數上限或段檔案的總大小。

Netflix 是如何實作每秒 200 萬次的資料處理?

在查詢資料時,Druid 将查詢發送到叢集中所有那些擁有的段所屬的時間塊在查詢範圍内的節點。在将中間結果發送回查詢代理節點之前,每個節點都并行地針對其持有的資料處理查詢。在将結果集發送回用戶端之前,代理将執行最後的合并和聚合。

Netflix 是如何實作每秒 200 萬次的資料處理?

攝取

這個資料庫的資料插入是實時的,不是将單個記錄插入到資料源中,而是從 Kafka 流讀取事件(就是我們的度量)。每個資料源使用一個主題。在 Druid 中,我們使用 Kafka 索引任務,它建立了多個分布在實時節點(中間管理器)上的索引工作器。

這些索引器都訂閱主題,并從流中讀取其事件。索引器根據攝取規範從事件消息中提取值,并将建立的行累積到記憶體中。一旦建立了一行,就可以查詢它。對于索引器正在填充的段的時間塊進行查詢,将由索引器本身提供服務。由于索引任務本質上是執行兩項工作,即攝取和處理查詢,是以及時将資料發送到曆史節點,以更優化的方式将查詢工作解除安裝給它們是很重要的。

Druid 可以在攝取時彙總資料,以盡量減少需要存儲的原始資料量。Rollup 是一種彙總或預聚合的形式。在某些情況下,彙總資料可以極大地減少需要存儲的資料的大小,可能會減少行數數量級。然而,這種存儲減少是有代價的:我們失去了查詢單個事件的能力,隻能在預定義的查詢粒度上進行查詢。對于我們的用例,我們選擇了 1 分鐘的查詢粒度。

在攝取期間,如果任何行具有相同的次元,并且它們的時間戳在同一分鐘内(我們的查詢粒度),則将這些行彙總。這意味着,通過将所有路徑成本相加合并行并增加計數器,我們就可以知道有多少事件對這一行的值有貢獻。這種形式的 Rollup 可以顯著地減少資料庫中的行數,進而加快查詢速度。

一旦累積的行數達到某個門檻值,或者段打開的時間太長,這些行就被寫入段檔案并被解除安裝到深層存儲中。然後,索引器通知協調器片段已經做好準備,以便協調器可以告訴一個或多個曆史節點來加載它。一旦段被成功地加載到曆史節點中,它就會從索引器中解除安裝,任何針對該資料的查詢現在都将由曆史節點提供服務。

資料管理

可以想象,随着次元基數的增加,在同一分鐘内發生相同僚件的可能性會降低。管理基數(以便彙總)是實作良好查詢性能的強大手段。

為了達到我們需要的攝取速度,可以運作許多索引器執行個體。即使索引任務使用 Rollup 合并相同的行,在一個索引任務的同一個執行個體中獲得這些相同行的機會也非常低。為了解決這個問題并實作盡可能好的 Rollup,我們會在給定時間塊的所有段都傳遞給曆史節點之後運作一個任務。

預定的壓縮任務從深度存儲中擷取時間塊的所有段,并運作 map/reduce 作業來重新建立段并實作完美的彙總。然後,由曆史節點加載和釋出新的段,替換和取代原來的、未充分彙總的段。在我們的例子中,通過使用這個額外的壓縮任務,行數減少到了 1/2。

知道何時收到給定時間塊的所有事件并不是一件小事。Kafka 上可能有延遲到達的資料,或者索引器将片段傳遞給曆史節點可能需要花些時間。為了解決這個問題,我們會在運作壓縮之前執行一些限制和檢查。

首先,我們丢棄所有非常晚才到達的資料。我們認為,這些資料在我們的實時系統已經過時。這設定了資料延遲的界限。其次,壓縮任務被延遲排程,這使得段有足夠的時間可以解除安裝到正常流中的曆史節點。最後,當給定時間塊的預定壓縮任務啟動時,它将查詢段中繼資料,檢查是否仍然有相關的段被寫入或傳遞。如果有,它将等待幾分鐘後再試一次。這将確定所有資料都由壓縮作業處理。

沒有這些措施,我們發現有時會丢失資料。在開始壓縮時仍有寫入的段将被新壓縮的段所覆寫,這些段具有更高的版本,是以會優先。這可以有效地删除包含在那些尚未完成傳遞的段中的資料。

查詢

Druid 支援兩種查詢語言:Druid SQL 和原生查詢。在底層,Druid SQL 查詢會被轉換成原生查詢。原生查詢以 JSON 格式送出給 REST 端點,這是我們使用的主要機制。

我們叢集的大多數查詢都是由自定義的内部工具(如儀表闆和預警系統)生成的。這些系統最初是為了與我們内部開發的開源時序資料庫 Atlas 一起工作而設計的。是以,這些工具使用 Atlas Stack 查詢語言。

為了加速查詢 Druid 的采用,并實作現有工具的重用,我們添加了一個翻譯層來接收 Atlas 查詢,将它們重寫為 Druid 查詢,發送查詢并将結果重新格式化為 Atlas 結果。這個抽象層允許現有的工具按原樣使用,使用者要通路我們 Druid 資料存儲中的資料也不需要額外學習。

調優

在調整叢集節點的配置時,我們以較高的速度運作一系列可重複和可預測的查詢,進而獲得每個給定配置的響應時間和查詢吞吐量的基準。這些查詢在設計時隔離了叢集的各個部分,以檢查查詢性能方面的改善或退化。

例如,我們對最近的資料進行有針對性的查詢,以便隻對 Middle Manager 進行查詢。同樣,對于較長的時間段但較舊的資料,我們隻查詢曆史節點來測試緩存配置。同樣,使用按高基數維分組的查詢檢查結果合并受到了什麼影響。我們繼續調整和運作這些基準測試,直到我們對查詢性能滿意為止。

在這些測試中,我們發現調整緩沖區的大小、線程的數量、查詢隊列的長度和配置設定給查詢緩存的記憶體對查詢性能有實際的影響。然而,壓縮作業的引入對查詢性能有更重要的影響,它會将未充分彙總的段重新壓縮,實作完美彙總。

我們還發現,在曆史節點上啟用緩存非常有好處,而在代理節點上啟用緩存效果則不是很明顯。是以,我們不在代理上使用緩存。這可能是由我們的用例造成的,但是幾乎每一次查詢都會錯過代理上的緩存,這可能是因為查詢通常包含最新的資料,這些資料不在任何緩存中,因為一直有資料到達。

小結

針對我們的用例和資料率,經過多次優化調整,Druid 已經被證明具備我們最初希望的能力。

我們已經能夠得到一個能力齊備、可用的系統,但仍然有更多的工作要做。随着查詢數量和複雜性的增加,我們的攝取量和速率也在不斷增加。随着更多的團隊認識到這些詳細資料的價值,我們經常需要添加更多的度量和次元,這加重了系統的負擔。我們必須繼續監控和調優,保證查詢性能受控。

目前,我們正在以每秒 200 萬次的速度處理事件,并查詢超過 1.5 萬億行的資料,以獲得關于使用者體驗服務的詳細資訊。所有這一切幫助我們保持了高品質的 Netflix 體驗,同時能夠不斷地創新。

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/zhibo

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-04-02

本文作者:Ben Sykes

本文來自:“

InfoQ

”,了解相關資訊可以關注“