譯者 | 李睿
審校 | 重樓
實(shí)時(shí)流架構(gòu)旨在連續(xù)地攝入、處理和分析數(shù)據(jù),從而實(shí)現(xiàn)近乎實(shí)時(shí)的決策和見解。它們需要具有低延遲,處理高吞吐量數(shù)據(jù)量,并且在發(fā)生故障時(shí)具有容錯(cuò)的能力。具備這些能力面臨的一些挑戰(zhàn)包括:
- 攝入——以高吞吐量從各種數(shù)據(jù)源、格式和結(jié)構(gòu)中攝入數(shù)據(jù),即使在大量數(shù)據(jù)流爆發(fā)期間也是如此。
- 處理——在確保有狀態(tài)計(jì)算、無序事件和數(shù)據(jù)延遲到達(dá)等復(fù)雜情況得到處理的同時(shí),以可擴(kuò)展和容錯(cuò)的方式確保恰好一次(Exactly-once)的處理語義。
- 實(shí)時(shí)分析——在不影響數(shù)據(jù)完整性或一致性的情況下,對(duì)從數(shù)據(jù)流源頭不斷攝入和處理的新數(shù)據(jù)實(shí)現(xiàn)低延遲的查詢響應(yīng)。
獨(dú)立的技術(shù)組件很難滿足所有的需求,這就是實(shí)時(shí)流架構(gòu)由多個(gè)協(xié)同工作的專用工具組成的原因。
一、Apache的Kafka、Flink、Pinot介紹
以下深入了解實(shí)時(shí)流架構(gòu)的核心技術(shù)——Apache Kafka、Apache Flink和Apache Pinot。
1.Apache Kafka
Apache Kafka是一個(gè)分布式流處理平臺(tái),是實(shí)時(shí)數(shù)據(jù)管道的中樞神經(jīng)系統(tǒng)。Apache Kafka的核心是圍繞發(fā)布-訂閱架構(gòu)構(gòu)建的,生產(chǎn)者將記錄發(fā)布到主題,消費(fèi)者訂閱這些主題來處理記錄。
Apache Kafka架構(gòu)的關(guān)鍵組件包括:
- 代理是存儲(chǔ)數(shù)據(jù)和服務(wù)客戶端的服務(wù)器。
- 主題是記錄發(fā)送到的類別。
- 分區(qū)是并行處理和負(fù)載平衡的主題劃分。
- 消費(fèi)者群體使多個(gè)消費(fèi)者能夠有效地協(xié)調(diào)和處理記錄。
Kafka是各行業(yè)實(shí)時(shí)數(shù)據(jù)處理和事件流的理想選擇,其主要功能包括:
- 高吞吐量
- 低延遲
- 容錯(cuò)性
- 耐用性
- 橫向可擴(kuò)展性
2.Apache Flink
Apache Flink是一個(gè)開源流處理框架,旨在對(duì)無界和有界數(shù)據(jù)流執(zhí)行有狀態(tài)計(jì)算。它的架構(gòu)圍繞分布式數(shù)據(jù)流引擎,確保應(yīng)用程序的高效和容錯(cuò)執(zhí)行。
Apache Flink的主要功能包括:
- 支持流和批處理
- 通過狀態(tài)快照和恢復(fù)進(jìn)行容錯(cuò)
- 事件時(shí)間處理
- 高級(jí)窗口功能
Apache Flink集成了各種各樣數(shù)據(jù)的源和匯——源是Apache Flink處理的輸入數(shù)據(jù)流,而匯是Apache Flink輸出處理過的數(shù)據(jù)的目的地。支持的Apache Flink源包括消息代理(例如Apache Kafka)、分布式文件系統(tǒng)(例如HDFS和S3)、數(shù)據(jù)庫和其他流數(shù)據(jù)系統(tǒng)。類似地,Apache Flink可以將數(shù)據(jù)輸出到各種各樣的接收器,包括關(guān)系數(shù)據(jù)庫、NoSQL數(shù)據(jù)庫和數(shù)據(jù)湖。
3.Apache Pinot
Apache Pinot是一個(gè)實(shí)時(shí)分布式在線分析處理(OLAP)數(shù)據(jù)存儲(chǔ),專為大規(guī)模數(shù)據(jù)流的低延遲分析而設(shè)計(jì)。Apache Pinot的架構(gòu)旨在有效地處理批處理數(shù)據(jù)和流數(shù)據(jù),提供即時(shí)查詢響應(yīng)。Apache Pinot擅長對(duì)從Kafka等數(shù)據(jù)流來源獲取的快速變化的數(shù)據(jù)進(jìn)行分析查詢。它支持多種數(shù)據(jù)格式,包括JSON、Avro和Parquet,并通過其分布式查詢引擎提供類似SQL的查詢功能。Pinot的星樹索引支持快速聚合、高效過濾、高維數(shù)據(jù)和壓縮。
二、Apache 的Kafka、Flink和Pinot集成
以下介紹Apache的Kafka、Flink和Pinot如何協(xié)同工作,對(duì)流數(shù)據(jù)進(jìn)行實(shí)時(shí)洞察、復(fù)雜事件處理和低延遲分析查詢的概述:
(1)Kafka作為一個(gè)分布式流媒體平臺(tái),從各種來源實(shí)時(shí)攝取數(shù)據(jù)。它為流數(shù)據(jù)提供持久、容錯(cuò)和可擴(kuò)展的消息隊(duì)列。
(2)Flink從Kafka主題中消耗數(shù)據(jù)流。它對(duì)傳入的數(shù)據(jù)執(zhí)行實(shí)時(shí)流處理、轉(zhuǎn)換和計(jì)算。Flink強(qiáng)大的流處理功能支持復(fù)雜的操作,例如窗口聚合、有狀態(tài)計(jì)算和基于事件時(shí)間的處理。然后將Flink的處理數(shù)據(jù)加載到Pinot中。
(3)Pinot攝入數(shù)據(jù)流,構(gòu)建實(shí)時(shí)和離線數(shù)據(jù)集,并為低延遲分析查詢創(chuàng)建索引。它支持一個(gè)類似SQL的查詢接口,并且可以對(duì)實(shí)時(shí)和歷史數(shù)據(jù)提供高吞吐量和低延遲的查詢。
圖1 Kafka、Flink和Pinot是實(shí)時(shí)流架構(gòu)的組件
以下深入了解各個(gè)組件:
1.Kafka攝入
Kafka提供了幾種攝入數(shù)據(jù)的方法,每種方法都有自己的優(yōu)點(diǎn)。使用Kafka生產(chǎn)者客戶端是最基本的方法。它提供了一種簡單有效的方法,可以將記錄從各種數(shù)據(jù)源發(fā)布到Kafka主題。開發(fā)人員可以通過將生產(chǎn)者客戶端集成到Kafka客戶端庫支持的大多數(shù)編程語言(Java、Python等)的應(yīng)用程序中來利用生產(chǎn)者客戶端。
生產(chǎn)者客戶端處理各種任務(wù),包括通過跨分區(qū)分發(fā)消息來實(shí)現(xiàn)負(fù)載平衡。這通過等待Kafka代理的確認(rèn)來確保消息的持久性,并管理失敗發(fā)送嘗試的重試。通過利用壓縮、批處理大小和逗留時(shí)間等配置,Kafka生產(chǎn)者客戶端可以針對(duì)高吞吐量和低延遲進(jìn)行優(yōu)化,使其成為Kafka實(shí)時(shí)數(shù)據(jù)攝取的高效可靠工具。
其他選擇包括:
- Kafka Connect是一個(gè)可擴(kuò)展和可靠的數(shù)據(jù)流工具,具有內(nèi)置功能,例如偏移管理、數(shù)據(jù)轉(zhuǎn)換和容錯(cuò)。它可以通過源連接器將數(shù)據(jù)讀入Kafka,也可以通過連接器將數(shù)據(jù)從Kafka寫入外部系統(tǒng)。
- Debezium在將數(shù)據(jù)攝入Kafka方面非常受歡迎,它使用源連接器來捕獲數(shù)據(jù)庫變更(插入、更新、刪除)。它將這些變更發(fā)布到Kafka主題中,以實(shí)現(xiàn)數(shù)據(jù)庫的實(shí)時(shí)更新。
Kafka生態(tài)系統(tǒng)也有一套豐富的第三方數(shù)據(jù)攝取工具。
2.Kafka-Flink集成
Flink提供了一個(gè)Kafka連接器,允許它在Kafka主題之間消費(fèi)和生成數(shù)據(jù)流。
連接器是Flink分布的一部分,它提供了容錯(cuò)性和恰好一次的語義。
連接器由兩部分組成:
- KafkaSource允許Flink使用來自一個(gè)或多個(gè)Kafka主題的數(shù)據(jù)流。
- KafkaSink允許Flink為一個(gè)或多個(gè)Kafka主題生成數(shù)據(jù)流。
以下是一個(gè)如何在Flink的數(shù)據(jù)流API中創(chuàng)建KafkaSource的例子:
Java
KafkaSource<String> source = KafkaSource.<String>builder()
.setBootstrapServers(brokers)
.setTopics("ad-events-topic")
.setGroupId("ad-events-app")
.setStartingOffsets(OffsetsInitializer.earliest())
.setValueOnlyDeserializer(new SimpleStringSchema())
.build();
DataStream<String> stream = env.fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");
需要注意的是,F(xiàn)linkKafkaConsumer基于遺留的SourceFunction API,已經(jīng)標(biāo)記為棄用并已刪除。新的基于數(shù)據(jù)源的API,包括KafkaSource,對(duì)水印生成、有界流(批處理)和動(dòng)態(tài)Kafka主題分區(qū)的處理等方面提供了更大的控制。
3.Flink-Pinot集成
有幾個(gè)選項(xiàng)可以將Flink與Pinot集成,將處理后的數(shù)據(jù)寫入Pinot表。
選項(xiàng)1:從Flink到Kafka再到Pinot
這是一個(gè)兩個(gè)步驟的過程,首先使用Flink Kafka連接器的KafkaSink組件將數(shù)據(jù)從Flink寫入Kafka。以下是一個(gè)示例:
Java
DataStream<String> stream = <existing stream>;
KafkaSink<String> sink = KafkaSink.<String>builder()
.setBootstrapServers(brokers)
.setRecordSerializer(KafkaRecordSerializationSchema.builder()
.setTopic("ad-events-topic")
.setValueSerializationSchema(new SimpleStringSchema())
.build()
)
.setDeliveryGuarantee(DeliveryGuarantee.AT_LEAST_ONCE)
.build();
stream.sinkTo(sink);
作為第二個(gè)步驟的一部分,在Pinot端,需要為Kafka配置實(shí)時(shí)攝取支持,它將實(shí)時(shí)攝取數(shù)據(jù)到Pinot表中。
這種方法解耦了Flink和Pinot,允許獨(dú)立擴(kuò)展它們,并潛在地利用架構(gòu)中其他基于Kafka的系統(tǒng)或應(yīng)用程序。
選項(xiàng)2:從Flink到Pinot(直接)
另一種選擇是使用作為Pinot發(fā)行版一部分的Flink SinkFunction。這種方法通過將流處理(或批處理)Flink應(yīng)用程序直接寫入指定的Pinot數(shù)據(jù)庫來簡化集成。這種方法簡化了管道,因?yàn)樗酥虚g步驟或額外組件的需要。它確保處理后的數(shù)據(jù)在Pinot中隨時(shí)可用,以實(shí)現(xiàn)低延遲查詢和分析。
三、優(yōu)秀實(shí)踐和注意事項(xiàng)
雖然在使用Kafka、Flink和Pinot進(jìn)行實(shí)時(shí)流解決方案時(shí)需要考慮很多因素,但這里有一些常見的因素。
1.恰好一次(Exactly-once)
恰好一次語義保證即使在出現(xiàn)故障或無序交付的情況下,每條記錄也只處理一次。實(shí)現(xiàn)這種行為需要流處理管道中涉及的組件之間的協(xié)調(diào)。
(1)使用Kafka的冪等設(shè)置來保證消息只傳遞一次。這包括在生產(chǎn)者上啟用enable.idempotence設(shè)置,并在消費(fèi)者上使用適當(dāng)?shù)母綦x級(jí)別。
(2)Flink的檢查點(diǎn)和偏移跟蹤確保只有處理過的數(shù)據(jù)被持久化,從而允許從故障中進(jìn)行一致的恢復(fù)。
(3)最后,Pinot的追加功能和唯一的記錄標(biāo)識(shí)符消除了攝入過程中的重復(fù),保持了分析數(shù)據(jù)集中的數(shù)據(jù)完整性。
2.Kafka-Pinot直接集成vs.使用Flink
直接集成Kafka和Pinot還是使用Flink作為中間層取決于流處理需求。如果需求涉及最小的流處理、簡單的數(shù)據(jù)轉(zhuǎn)換或較低的操作復(fù)雜性,可以使用Kafka內(nèi)置的支持將Kafka與Pinot直接集成,以從Kafka主題中消費(fèi)數(shù)據(jù)并將其攝入實(shí)時(shí)表中。此外,可以在攝入過程中在Pinot中執(zhí)行簡單的轉(zhuǎn)換或過濾,從而消除了對(duì)專用流處理引擎的需求。
如果用例需要復(fù)雜的流處理操作,例如窗口聚合、有狀態(tài)計(jì)算、基于事件時(shí)間的處理或從多個(gè)數(shù)據(jù)源攝取,則建議使用Flink作為中間層。Flink提供強(qiáng)大的流處理API和操作符來處理復(fù)雜的場景,提供跨應(yīng)用程序的可重用處理邏輯,并且可以在將流數(shù)據(jù)攝取到Pinot之前對(duì)流數(shù)據(jù)執(zhí)行復(fù)雜的提取-轉(zhuǎn)換-加載(ETL)操作。在具有復(fù)雜流需求的場景中,引入Flink作為中間流處理層可能是有益的,但它也增加了操作的復(fù)雜性。
3.可擴(kuò)展性和性能
處理大量數(shù)據(jù)并確保實(shí)時(shí)響應(yīng)需要仔細(xì)考慮整個(gè)管道的可擴(kuò)展性和性能。討論最多的兩個(gè)方面包括:
(1)可以利用這三個(gè)組件固有的水平可擴(kuò)展性。添加更多Kafka代理來處理數(shù)據(jù)攝取量,擁有多個(gè)Flink應(yīng)用實(shí)例來并行處理任務(wù),并擴(kuò)展Pinot服務(wù)器節(jié)點(diǎn)來分配查詢執(zhí)行。
(2)可以基于常用查詢過濾器對(duì)數(shù)據(jù)進(jìn)行分區(qū)來有效地利用Kafka分區(qū),從而提高Pinot中的查詢性能。通過在工作節(jié)點(diǎn)之間均勻分布數(shù)據(jù),分區(qū)也有利于Flink的并行處理。
4.常用用例
可能正在使用構(gòu)建在實(shí)時(shí)流架構(gòu)之上的解決方案,有些人甚至沒有意識(shí)到這一點(diǎn)。以下將介紹幾個(gè)常用示例。
(1)實(shí)時(shí)廣告
現(xiàn)代廣告平臺(tái)需要做的不僅僅是提供廣告,還必須處理廣告拍賣、競價(jià)和實(shí)時(shí)決策等復(fù)雜流程。一個(gè)值得注意的例子是Uber公司的UberEats應(yīng)用程序,廣告事件處理系統(tǒng)必須以最小的延遲發(fā)布結(jié)果,同時(shí)確保沒有數(shù)據(jù)丟失或重復(fù)。為了滿足這些需求,Uber公司使用Kafka、Flink和Pinot構(gòu)建了一個(gè)系統(tǒng)來實(shí)時(shí)處理廣告事件流。
該系統(tǒng)依賴于Flink作業(yè)通過Kafka主題進(jìn)行通信,最終用戶數(shù)據(jù)存儲(chǔ)在Pinot(Apache Hive)中。通過結(jié)合Kafka和Flink提供的恰好一次語義、Pinot中的追加功能以及用于重復(fù)數(shù)據(jù)刪除和冪等性的唯一記錄標(biāo)識(shí)符的組合來保持準(zhǔn)確性。
(2)面向用戶的分析
當(dāng)涉及到延遲和吞吐量時(shí),面向用戶的分析有非常嚴(yán)格的要求。LinkedIn已經(jīng)廣泛采用Pinot來支持整個(gè)公司的各種實(shí)時(shí)分析用例。Pinot作為幾個(gè)面向用戶的產(chǎn)品特性的后端,包括“誰查看了我的個(gè)人資料”。Pinot支持對(duì)大量數(shù)據(jù)集的低延遲查詢,允許LinkedIn為其成員提供高度個(gè)性化和最新的體驗(yàn)。除了面向用戶的應(yīng)用程序,Pinot還被用于LinkedIn的內(nèi)部分析,并為各種內(nèi)部儀表板和監(jiān)控工具提供支持,使團(tuán)隊(duì)能夠?qū)崟r(shí)了解平臺(tái)性能、用戶參與度和其他運(yùn)營指標(biāo)。
(3)欺詐檢測(cè)
對(duì)于欺詐檢測(cè)和風(fēng)險(xiǎn)管理場景,Kafka可以攝入與交易數(shù)據(jù)、用戶活動(dòng)和設(shè)備信息相關(guān)的實(shí)時(shí)數(shù)據(jù)流。Flink的管道可以應(yīng)用模式檢測(cè)、異常檢測(cè)、基于規(guī)則的欺詐檢測(cè)和數(shù)據(jù)豐富等技術(shù)。Flink的有狀態(tài)處理能力能夠在數(shù)據(jù)流經(jīng)管道時(shí)維護(hù)和更新用戶或事務(wù)級(jí)狀態(tài)。處理后的數(shù)據(jù),包括標(biāo)記的欺詐活動(dòng)或風(fēng)險(xiǎn)評(píng)分,然后轉(zhuǎn)發(fā)給Pinot。
風(fēng)險(xiǎn)管理團(tuán)隊(duì)和欺詐分析師可以在Pinot實(shí)時(shí)數(shù)據(jù)的基礎(chǔ)上執(zhí)行臨時(shí)查詢或構(gòu)建交互式儀表板。這可以識(shí)別高風(fēng)險(xiǎn)用戶或交易,分析欺詐活動(dòng)的模式和趨勢(shì),監(jiān)控實(shí)時(shí)欺詐指標(biāo)和KPI,并調(diào)查標(biāo)記為潛在欺詐的特定用戶或交易的歷史數(shù)據(jù)。
結(jié)論
Kafka的分布式流平臺(tái)支持高吞吐量的數(shù)據(jù)攝取,而Flink的流處理能力允許復(fù)雜的轉(zhuǎn)換和有狀態(tài)的計(jì)算。最后,Pinot的實(shí)時(shí)OLAP數(shù)據(jù)存儲(chǔ)促進(jìn)了低延遲的分析查詢,使組合解決方案成為需要實(shí)時(shí)決策和見解的用例的理想選擇。
雖然Kafka、Flink和Pinot等單個(gè)組件非常強(qiáng)大,但在云計(jì)算和內(nèi)部部署之間大規(guī)模管理它們?cè)诓僮魃峡赡芎軓?fù)雜。托管流媒體平臺(tái)減少了操作開銷,并抽象出許多低級(jí)集群配置、配置、監(jiān)控和其他操作任務(wù)。它們?cè)试S根據(jù)不斷變化的工作負(fù)載需求彈性地增加或減少資源配置。這些平臺(tái)還為關(guān)鍵功能提供集成工具,例如跨所有組件監(jiān)視、調(diào)試和測(cè)試流應(yīng)用程序。
要了解更多信息,可以參閱Apache Kafka、Apache Flink和Apache Pinot的官方文檔和示例。圍繞這些項(xiàng)目的社區(qū)也有豐富的資源,包括書籍、教程和技術(shù)講座,涵蓋了現(xiàn)實(shí)世界的用例和最佳實(shí)踐。
額外的資源:
- Apache Kafka Patterns and Anti-Patterns by Abhishek Gupta, DZone Refcard
- Apache Kafka Essentials by Sudip Sengupta, DZone Refcard
原文標(biāo)題:Real-Time Streaming Architectures: A Technical Deep Dive Into Kafka, Flink, and Pinot,作者:Abhishek Gupta