Categories
程式開發

每年150億美元花哪了? Netflix的大規模Kafka實踐


Netflix在2019年花費了大約150億美元來製作世界一流的原創內容。在如此高的投入之下,我們必須獲得許多關鍵的業務見解,從而為所有Netflix內容的策劃、預算和效益分析工作提供幫助。這些見解可以是以下內容:

  • 明年我們應該花費多少錢採購國外電影和電視劇?
  • 我們是否快要超出製作預算了,是否需要有人介入把事情扳回正軌?
  • 我們如何利用數據、直覺和分析能力來提前規劃全年的採播方案,盡可能做到完美的計劃?
  • 我們如何為來自全球的內容生成財務數據並向華爾街報告?

就像風險投資人精挑細選優秀的投資機會一樣,Netflix的內容財務工程團隊旨在幫助Netflix投資、追踪並從我們的行動中學習經驗,以便在未來不斷做出更好的投資。

擁抱事件

從工程的角度來看,每個財務應用程序都是一個微服務。 Netflix擁護分佈式治理的理念,並鼓勵工程師在應用程序中使用微服務驅動的方法,從而在公司擴張時實現數據抽象和速度之間的適當平衡。在一個簡單的環境中,服務之間可以通過HTTP進行良好的交互,但是隨著我們的擴張,它們演變成了由同步交互請求組成的複雜網絡。這有可能導致腦裂,並破壞可用性。

每年150億美元花哪了? Netflix的大規模Kafka實踐 1

上圖中的這些實體是相互關聯的。假設某個節目的製作日期發生了變化,就會影響我們的節目播出計劃,進而影響現金流項目、薪水支付和年度預算等。在微服務架構中,某種程度的失敗通常是可以接受的。但是,對內容財務工程的任何微服務調用失敗都會打亂一大堆計算結果,並可能導致數百萬美元的損失。調用關係變得更為複雜時還會導致可用性問題,並在試圖有效地跟踪和回答業務問題時產生盲點,例如:為什麼現金流預測與我們的發佈時間表不一致?為什麼對本年度的預測未考慮正在製作中的節目?我們何時可以看到成本報告能夠準確反映上游的變化?

當我們重新審視服務間的交互,並將它們視為事件交換流(而非一系列同步請求)後,我們就構建出了異步的基礎架構。這種架構促進了解耦,並為分佈式事務網絡提供了可追溯性。事件不僅僅是觸發器和更新,它們成為了不可變的流,我們可以基於事件流重構整個系統的狀態。

我們轉向發布訂閱模型後,每個服務都可以將變更作為事件發佈到消息總線中,然後這些事件被需要調整自身狀態的服務消費。借助這種模型,我們能夠跟踪各種服務的狀態是否同步,如果還沒有,它們還需要多長時間才能回到同步狀態。當我們面對的是一大堆互相依賴的服務時,這些見解是非常有用的。基於事件的通信和去中心化的事件處理幫助我們解決了許多問題,這些問題在大型同步調用圖中是很常見的(如上所述)。

Netflix選擇了Apache Kafka作為處理事件、消息傳遞和流處理的事實標準。 Kafka充當所有點對點和Netflix Studio範圍內通信的橋樑。它為我們提供了Netflix操作系統所需的高持久性和線性可擴展的多租戶架構。我們內部的Kafka即服務產品提供了容錯能力、可觀察性、多區域部署和自助服務。這使我們的整個微服務生態系統更容易地生產和消費有意義的事件,並釋放出了異步通信的強大能量。

Netflix Studio生態系統中的一次典型消息交換過程如下所示:

每年150億美元花哪了? Netflix的大規模Kafka實踐 2

我們可以將它們分解為三大子組件。

生產者

生產者可以是任何系統,當這個系統想要發布其完整狀態,或要表明其內部狀態的某個關鍵部分已針對特定實體做出了更改,它就成是生產者。一個事件除了內容負載外,還需要遵循規範化的格式,以便於跟踪和理解。這種格式包括:

  • UUID:通用唯一標識符
  • Type:創建、讀取、更新或刪除(CRUD)這四種類型之一
  • Ts:事件的時間戳

變更數據捕獲(CDC)工具是另一類事件生產者,它將數據庫變更作為事件。當你要讓數據庫變更對多個消費者可見時,這個工具就很有用了。我們還使用這個模式來跨數據中心複製相同的數據(對於單個主數據庫)。例如,當MySQL中的數據需要被索引到Elasticsearch或Apache Solr中時,就會用到這個工具。使用CDC的好處是它不會給源應用程序增加額外的負載。

對於CDC事件,可以根據事件格式的TYPE字段為相應的數據槽轉換事件。

強化器(Enricher)

在數據進入Kafka後,便可以對其應用各種消費模式。事件有多種用法,包括作為系統計算的觸發器、作為近實時通信的內容傳輸負載,以及作為增強和物化數據內存視圖的線索。

當微服務需要數據集的完整視圖,但部分數據是來自另一個服務的數據集時,數據增強方法的應用就會愈加普遍。聯接的數據集可用於提升查詢性能或提供聚合數據的近實時視圖。為了豐富事件數據,消費者從Kafka中讀取數據並調用其他服務(使用gRPC和GraphQL等方法)來構造聯接的數據集,然後將其發送到其他Kafka主題。

每年150億美元花哪了? Netflix的大規模Kafka實踐 3

增強過程可以作為單獨的微服務運行,該微服務負責執行扇出(fanout)和物化數據集。在某些情況下,我們希望進行更複雜的處理,例如基於時間窗口、會話的處理和狀態管理等。對於這種情況,建議使用成熟的流處理引擎來構建業務邏輯。在Netflix,我們使用Apache Flink和RocksDB來做流處理。我們也在考慮使用ksqlDB(https://ksqldb.io/)。

事件的順序

財務數據集的一項關鍵需求是事件的順序。在Kafka中,我們可以通過發送帶有鍵的消息來實現這一目的。使用相同鍵發送的事件或消息都能保證正確的順序,因為它們被發送到了相同的分區。但是,生產者仍然可以弄亂事件的順序。

例如,“Stranger Things”的發行日期先是從7月移至6月,然後又從6月移至7月。由於種種原因,這些事件可能會按照錯誤的順序寫入Kafka(可能因為生產者到Kafka的網絡超時、生產者代碼中的並發錯誤等)。一個很小的順序錯誤可能會嚴重影響許多財務計算結果。

為了避免這種情況,建議生產者只發送發生變更的實體的主要ID,而不發送Kafka消息的完整內容。增強過程(如前所述)使用實體的ID查詢源服務,以獲取最新的狀態或內容,從而提供了一種很好的方式來解決順序錯亂問題。我們將其稱為延遲物化(delayed materialization),它可以保證數據集的順序是正確的。

每年150億美元花哪了? Netflix的大規模Kafka實踐 4

消費者

我們使用Spring Boot來實現微服務,這些服務從Kafka主題讀取數據。 Spring Boot提供了很棒的內置Kafka消費者(稱為Spring Kafka Connector),可以無縫消費,並提供了簡便的註解(annotation),用於消費和反序列化數據。

關於數據,還需要討論的一個概念是合約。隨著事件流用得越來越多,我們最終得到了一組互不相同的數據集,其中一些數據集被大量應用程序消費。在這些情況下,在輸出上定義一種schema是理想的選擇,並有助於確保向後兼容。為此,我們利用Confluent Schema Registry和Apache Avro來構建帶有schema的流。

每年150億美元花哪了? Netflix的大規模Kafka實踐 5

除了專有的微服務消費者外,我們還有CDC數據槽,將數據索引到多種存儲中,以便進行進一步的分析。其中包括用於關鍵字搜索的Elasticsearch、用於審記的Apache Hive,以及用於進一步下游處理的Kafka。這些數據的內容可以直接來自Kafka消息,並使用ID字段作為主鍵,根據TYPE字段進行CRUD操作。

每年150億美元花哪了? Netflix的大規模Kafka實踐 6

消息傳遞保證

在分佈式系統中,保證一次僅一次消息傳遞並不是一件容易的事情,因為涉及的組件太多,太過複雜。消費者行為應該具有冪等性,以應對任何潛在的基礎設施和生產者故障。

但即使應用程序是冪等的,也不應該為已處理過的消息進行重複繁重的計算。為了做到這一點,一種流行方法是通過分佈式緩存來跟踪消息的UUID,只要在到期時間間隔內遇到相同的UUID,就不進行重複處理。

Flink在內部使用RocksDB實現狀態管理,使用鍵作為消息的UUID,以此來實現只處理一次。如果你只想使用Kafka,Kafka Streams也提供了一種方法。基於Spring Boot的應用程序可以使用EVCache

每年150億美元花哪了? Netflix的大規模Kafka實踐 7

監控基礎架構服務水平

對於Netflix來說,實時查看其基礎架構中的服務水平是至關重要的。 Netflix開發了Atlas來管理維度時間序列數據,我們用它可視化指標。我們使用生產者、處理器和消費者發布的各種指標來幫助我們構建整個基礎架構的近實時視圖。

每年150億美元花哪了? Netflix的大規模Kafka實踐 8

我們監控的一些關鍵指標有:

  • 新鮮度SLA
    • 從事件的產生到事件到達所有數據槽的時間是多少?
    • 每個消費者的處理延遲是多少?
  • 最大傳輸速率
    • 我們能夠發送多大載荷?
    • 我們應該壓縮數據嗎?
  • 分區和並行化
    • 我們是否有效地利用了我們的資源?
    • 我們可以更快地消費嗎?
  • 故障轉移和恢復
    • 我們是否可以為狀態創建檢查點並在發生故障時恢復?
  • 背壓
    • 如果我們無法跟上事件流的速度,是否可以在不使應用程序崩潰的前提下對相應的源應用背壓?
  • 負載分配
    • 我們如何處理事件爆發?
    • 我們是否有足夠的資源來滿足SLA?

總結

Netflix Studio製作和財務團隊選擇了分佈式治理作為系統的架構方式。我們使用Kafka作為處理事件的首選平台,幫助我們在基礎架構中實現了更高的可見性和更好的解耦,同時幫助我們有機地擴展了運營工作。它是Netflix Studio基礎設施變革以及隨之而來的電影工業變革浪潮中的核心角色。

如果你想了解更多信息,可以查看我在Kafka舊金山峰會演講:Eventing Things – A Netflix Original的錄像和幻燈片

作者介紹:

Nitin Sharma是Netflix內容財務基礎架構團隊的一名分佈式系統工程師,他在構建和運營大型分佈式基礎架構方面已有十多年的經驗。他曾從事數據存儲、搜索平台、事件驅動的架構,流處理、消息傳遞和機器學習基礎架構方面的工作。他是一名狂熱的技術演講者,並在諸多國際會議上發表過演講。

原文鏈接

https://www.confluent.io/blog/how-kafka-is-used-by-netflix/