使用Kafka和Flink構建實時資料處理系統
引言
在很多領域,如股市走向分析, 氣象資料測控,網站使用者行為分析等,由於資料產生快,實時性強,資料量大,所以很難統一採集併入庫儲存後再做處理,這便導致傳統的資料處理架構不能滿足需要。流計算的出現,就是為了更好地解決這類資料在處理過程中遇到的問題。與傳統架構不同,流計算模型在資料流動的過程中實時地進行捕捉和處理,並根據業務需求對資料進行計算分析,最終把結果儲存或者分發給需要的元件。本文將從實時資料產生和流向的各個環節出發,通過一個具有實際意義的案例,向讀者介紹如何使用 Apache Kafka 和 Apache Flink 構建一個實時的資料處理系統,當然本文只是拋磚引玉,因為構建一個良好健壯的實時資料處理系統並不是一篇文章可以說清楚的。在閱讀本文前,假設您已經對 Apache Kafka 分散式訊息系統有了基本的瞭解,並且可以使用 Flink SQL 編寫業務邏輯。接下來,就讓我們一起看看如何構建一個簡易的實時資料處理系統吧。
關於Kafka
Kafka 是一個分散式的,高吞吐量,易於擴充套件地基於主題釋出/訂閱的訊息系統,最早是由 Linkedin 開發,並於 2011 年開源並貢獻給 Apache 軟體基金會。一般來說,Kafka 有以下幾個典型的應用場景:
-
作為訊息佇列。由於 Kafka 擁有高吞吐量,並且內建訊息主題分割槽,備份,容錯等特性,使得它更適合使用在大規模,高強度的訊息資料處理的系統中。
-
流計算系統的資料來源。流資料產生系統作為 Kafka 訊息資料的生產者將資料流分發給 Kafka 訊息主題,流資料計算系統 (Flink,Storm,Spark Streaming等) 實時消費並計算資料。這也是本文將要介紹的應用場景。
-
系統使用者行為資料來源。這種場景下,系統將使用者的行為資料,如訪問頁面,停留時間,搜尋日誌,感興趣的話題等資料實時或者週期性的釋出到 Kafka 訊息主題,作為對接系統資料的來源。
-
日誌聚集。Kafka 可以作為一個日誌收集系統的替代解決方案,我們可以將系統日誌資料按類別彙集到不同的 Kafka 訊息主題中。
-
事件源。在基於事件驅動的系統中,我們可以將事件設計成合理的格式,作為 Kafka 訊息資料儲存起來,以便相應系統模組做實時或者定期處理。由於 Kafka 支援大資料量儲存,並且有備份和容錯機制,所以可以讓事件驅動型系統更加健壯和高效。
當然 Kafka 還可以支援其他的應用場景,在這裡我們就不一一羅列了。關於 Kafka 更詳細的介紹,請讀者參考Kafka 官網。需要指出的是,本文使用的 Kafka 版本是基於 Scala 2.10 版本構建的 0.8.2.1 版本。
關於Flink
Flink支援多種資料來源:Kafka、MQ、SLS、Datahub 等,原生支援寫入到 MQ、OTS、常見關聯式資料庫等儲存介質,提供了不同的抽象級別以開發流式或批處理應用。
-
最底層級的抽象僅僅提供了有狀態流。它將通過過程函式(Process Function)嵌入到DataStream API中。它允許使用者可以自由地處理來自一個或多個流資料的事件,並使用一致、容錯的狀態。除此之外,使用者可以註冊事件時間和處理事件回撥,從而使程式可以實現複雜的計算。
-
實際上,大多數應用並不需要上述的低層級抽象,而是針對 核心API(Core APIs) 進行程式設計,比如DataStream API(有界或無界流資料)以及DataSet API(有界資料集)。這些流暢的API為資料處理提供了通用的構建模組,比如由使用者定義的多種形式的轉換(transformations),連線(joins),聚合(aggregations),視窗操作(windows),狀態(state)等等。這些API處理的資料型別以類(classes)的形式由各自的程式語言所表示。
低層級的 過程函式 與 DataStream API 相整合,使其可以對某些特定的操作進行低層級的抽象。DataSet API 為有界資料集提供了額外的原語,例如迴圈與迭代。
-
Table API 是以 表 為中心的宣告式DSL,其中表可能會動態變化(在表達流資料時)。Table API遵循(擴充套件的)關係模型:表具有附加的模式(類似於關聯式資料庫中的表),同時API提供可比較的操作,例如select、project、join、group-by、aggregate等。Table API程式宣告式地定義了 什麼邏輯操作應該執行 而不是準確地確定 這些操作程式碼的看上去如何 。 儘管Table API可以通過多種型別的使用者定義的函式進行擴充套件,其仍不如 核心API 更具表達能力,但是使用起來卻更加簡潔(程式碼量更少)。除此之外,Table API程式還可以在執行之前通過應用優化規則的優化器。
你可以在表與 DataStream/DataSet 之間無縫切換,以允許程式將 Table API 與 DataStream 以及 DataSet 混合使用。
-
Flink提供的最高層級的抽象是 SQL 。這一層抽象在語法與表達能力上與 Table API 類似,但是是以SQL查詢表示式的形式表現程式。SQL抽象與Table API互動密切,同時SQL查詢可以直接在Table API定義的表上執行。
案例介紹與Flink SQL程式設計實現
1.案例介紹
該案例中,我們假設某論壇需要根據使用者對站內網頁的點選量,停留時間,以及是否點贊,來近實時的計算網頁熱度,進而動態的更新網站的今日熱點模組,把最熱話題的連結顯示其中。
2.案例分析
對於某一個訪問論壇的使用者,我們需要對他的行為資料做一個抽象,以便於解釋網頁話題熱度的計算過程。
首先,我們通過一個向量來定義使用者對於某個網頁的行為即點選的網頁,開始時間,停留時間,以及是否點贊,可以表示如下:
(page001.html,0, 1, 0.5, 1)
向量的第一項表示網頁的 ID,第二項表示使用者網頁開始點選時間,第三項表示從進入網站到離開對該網頁的點選次數,第四項表示停留時間,以秒為單位,第五項是代表是否點贊,1 為贊,-1 表示踩,0 表示中立。
其次,我們再按照各個行為對計算網頁話題熱度的貢獻,給其設定一個權重,在本文中,我們假設點選次數權重是 0.8,因為使用者可能是由於沒有其他更好的話題,所以再次瀏覽這個話題。停留時間權重是 0.8,因為使用者可能同時開啟多個 tab 頁,但他真正關注的只是其中一個話題。是否點贊權重是 1,因為這一般表示使用者對該網頁的話題很有興趣。
最後,我們定義用下列公式計算某條行為資料對於該網頁熱度的貢獻值。
f(x,y,z)=0.8x+0.8y+z
那麼對於上面的行為資料 (page001.html, 1, 0.5, 1),利用公式可得:
H(page001)=f(x,y,z)= 0.8x+0.8y+z=0.8*1+0.8*0.5+1*1=2.2
讀者可以留意到,在這個過程中,我們忽略了使用者本身,也就是說我們不關注使用者是誰,而只關注它對於網頁熱度所做的貢獻。
3.生產行為資料資訊
在本案例中我們將使用一段程式來模擬使用者行為,該程式每隔 5 秒鐘會隨機的向 user-behavior-topic 主題推送 0 到 50 條行為資料訊息,顯然,這個程式扮演訊息生產者的角色,在實際應用中,這個功能一般會由一個系統來提供。為了簡化訊息處理,我們定義訊息的格式如下:
網頁 ID|開始點選時間|點選次數|停留時間 (分鐘)|是否點贊
ID(varchar)|firsttime(timestamp)|count(bigint)|timegap(bigint)|positive(boolean)
4.編寫Flink SQL編寫程式實時處理資料
在弄清楚了要解決的問題之後,就可以開始編碼實現了。對於本案例中的問題,在實現上的基本步驟如下:
-
建立源表和結果表
-
建立子查詢,使用 ROW_NUMBER() 視窗函式來對資料根據排序列進行排序並標上排名
-
外層查詢中,對排名進行過濾,只取前N條,如N=5,那麼就是取 Top 5 的資料,即網頁熱度排名
-- Kafka源表
create table input(
id varchar,
count bigint,
timegap bigint,
positive boolean,
firsttime timestamp,
WATERMARK wk FOR firsttime as withOffset(firsttime, 2000)
)with(
type=`kafka`
endpoint=`xxx`
......
);
-- Hbase儲存表
create table output(
window_start TIMESTAMP,
window_end TIMESTAMP,
id bigint,
contribution double
)with(
type=`ALIHBASE`
endpoint=`xxx`
......
);
-- 5秒鐘視窗貢獻度統計
CREATE VIEW group_view AS
SELECT id,
TUMBLE_START(firsttime, INTERVAL `5` SECOND) AS start_time,
(0.8*count+0.8*timegap+positive) as contribution
FROM input
GROUP BY id, TUMBLE(firsttime, INTERVAL `1` MINUTE);
-- 統計每5秒 top5 貢獻值ID,並輸出
insert into output
select
(
SELECT
id, firsttime, contribution,
ROW_NUMBER() OVER (PARTITION BY firsttime ORDER BY contribution DESC) as rownum,
FROM
group_view
)
WHERE rownum <= 5;
注意事項
利用 Flink 構建一個高效健壯的流資料計算系統,我們還需要注意以下方面。
-
需要合理的設定時間視窗,即需要保證Flink的計算視窗合理地統計到熱度最高的話題,理論上Flink的視窗可以是無界的,也可以是很小的時間視窗,但是合理的視窗大小設計對業務邏輯的影響。
-
雖然本文案例中,我們只是把 (近) 實時計算結果列印出來,但是實際上很多時候這些結果會被儲存到資料庫,HDFS, 或者傳送回 Kafka, 以供其他系統利用這些資料做進一步的業務處理,Flink可以直接實現這些功能。
-
由於流計算對實時性要求很高,所以任何由於 JVM Full GC 引起的系統暫停都是不可接受的。Flink 採用類似 DBMS 的 sort 和 join 演算法,直接操作二進位制資料,從而使序列化/反序列化帶來的開銷達到最小。所以 Flink 的內部實現更像 C/C++ 而非 Java。如果需要處理的資料超出了記憶體限制,則會將部分資料儲存到硬碟上。如果要操作多塊MemorySegment就像操作一塊大的連續記憶體一樣,Flink會使用邏輯檢視(
AbstractPagedInputView
)來方便操作。 -
Flink內部支援exactly-once,要想達到端到端(Soruce到Sink)的exactly-once,需要Blink外部Soruce和Sink的支援,比如Source要支援精準的offset,Sink要支援兩階段提交,也就是繼承TwoPhaseCommitSinkFunction。
-
Flink中當所有輸入的barrier沒有完全到來的時候,早到來的event在exactly-once的情況向會進行快取(不進行處理),而at-least-once的模式下即使所有輸入的barrier沒有完全到來的時候,早到來的event也會進行處理。也就是說對於at-least-once模式下,對於下游節點而言,本來資料屬於checkpoint n的資料在checkpoint n-1裡面也可能處理過了。所以我們建議,Flink的checkpoint模式設定為exactl-once模式。
結束語
本文包含了整合Flink和 Kafka 分散式訊息系統的基本知識,但是需要指出的是,在實際問題中,我們可能面臨更多的問題,如效能優化,記憶體不足,以及其他未曾遇到的問題。希望通過本文的閱讀,讀者能對使用 Flink SQL 和 Kafka 構建實時資料處理系統有一個基本的認識,為讀者進行更深入的研究提供一個參考依據。讀者在閱讀本文的時候發現任何問題或者有任何建議,請不吝賜教,留下您的評論,我會及時回覆。希望我們可以一起討論,共同進步。
相關文章
- 實時資料處理:Kafka 和 FlinkKafka
- DoorDash使用 Kafka 和 Flink 構建可擴充套件的實時事件處理Kafka套件事件
- 使用Storm、Kafka和ElasticSearch處理實時資料 -javacodegeeksORMKafkaElasticsearchJava
- 開源實時資料處理系統Pulsar:一套搞定Kafka+Flink+DBKafka
- 使用 .NET Core 構建可擴充套件的實時資料處理系統套件
- flink使用Event_time處理實時資料
- 使用Python構建MySQL資料處理系統的操作方法PythonMySql
- 日處理資料量超10億:友信金服基於Flink構建實時使用者畫像系統的實踐
- 優步是如何使用Apache Flink和Kafka實現實時Exactly-Once廣告事件處理?ApacheKafka事件
- Kafka+Flink 實現準實時異常檢測系統Kafka
- 使用 Go 和 ReactJS 構建聊天系統(四):處理多個客戶端GoReactJS客戶端
- 基於flink和drools的實時日誌處理
- 基於實時計算(Flink)與高斯模型構建實時異常檢測系統模型
- 使用 Flink Hudi 構建流式資料湖平臺
- kafka和websocket實時資料推送KafkaWeb
- 解構流儲存 — Pravega,與 Flink 構建端到端的大資料流水處理線大資料
- 使用Kafka Streams構建事件源系統的經驗Kafka事件
- 實時資料架構體系建設指南架構
- 大資料平臺之大資料處理系統的架構大資料架構
- Hadoop高階資料分析 使用Hadoop生態系統設計和構建大資料系統Hadoop大資料
- Flink基礎:實時處理管道與ETL
- 數棧產品分享:基於StreamWorks構建實時大資料處理平臺大資料
- 大資料流處理:Flume、Kafka和NiFi對比大資料KafkaNifi
- Debezium zookeeper kafka mysql資料處理KafkaMySql
- Flink CDC 系列 - 同步 MySQL 分庫分表,構建 Iceberg 實時資料湖MySql
- 實時計算Flink——獨享模式系統架構模式架構
- RocketMQ Connect 構建流式資料處理平臺MQ
- 支付類系統資料處理和資料中臺的資料處理方式有什麼不同?
- 爬蟲架構|利用Kafka處理資料推送問題(2)爬蟲架構Kafka
- 解密Kafka主題的分割槽策略:提升實時資料處理的關鍵解密Kafka
- B 站構建實時資料湖的探索和實踐
- 大資料6.1 - 實時分析(storm和kafka)大資料ORMKafka
- 三種大資料流處理框架選擇比較:Apache Kafka流、Apache Spark流和Apache Flink - quora大資料框架ApacheKafkaSpark
- 使用inotify-tools與rsync構建實時備份系統
- 優步是如何用Kafka構建可靠的重試處理保證資料不丟失Kafka
- 讀構建可擴充套件分散式系統:方法與實踐14流處理系統套件分散式
- Apache Flink 如何正確處理實時計算場景中的亂序資料Apache
- Kafka能做什麼?十分鐘構建你的實時資料流管道Kafka