作者 | 鄧小勇(靜行),阿裡巴巴進階技術專家
本文由阿裡巴巴進階技術專家鄧小勇(靜行)分享,主要用 Demo 示範如何通過實時計算 Flink 實時計算pv/uv的場景。内容将從以下幾部分進行:
- App 計算 pv/uv 場景
- 實作方案(From Flink-1.11)
- DDL
- DML
- 實操
首先為大家展示一個比較簡單的pv/uv場景。以下圖所示的APP為例,整個業務構架需要幾個入口,包括使用者通路入口、作者入口和營運人員入口。在營運人員入口進去可以檢視系統的一些名額,比如app 的pv/uv。

在開始介紹如何計算實時pv/uv之前,可以先了解下上圖的10個字段和它們對應的含義。通過這些字段可以了解到,使用者在APP上的任何一次操作都會在資料庫中留下一條對應的記錄,所有記錄就是該使用者在APP上的操作流水。
那麼如何實時計算pv/uv呢?
有兩種方案。
方案一,MySQL的變更資料同步到Kafka後進行實時計算。由于 Flink在設計之初是具有流表二象性的,是以在 Flink 1.1版本之後,就可以實作 Flink 對 Kafka變更資料的處理了,包括處理一些修改、删除等操作。處理後的結果會放到阿裡雲Hologress裡,友善使用者進行大資料查詢和分析。
方案二,從上圖可以看到方案一比方案二隻多了一個Kafka,在 Flink 1.11 版本之後,可以直接通過Debezium連接配接MySQL,然後經過Flink 實時計算,也可以完成同樣功能。
兩個方案都可以實作,那麼如何選擇呢?主要取決于業務。如果資料隻是暫存,日志需要展示或是需要多個下遊使用,需要儲存到Kafka;如果日志不需要回溯,或是沒有下遊使用,那麼方案二更适合。
實戰示範
如下圖所示,我們選擇方案二(MySQL-CDC源表方式)來示範。
首先打開實時計算 Flink平台,點選左側SQL編輯器,然後通過Create Table方式設定上文提到的10個字段。這樣就定義了資料的源頭。
定義源頭之後,接下來要建構目标表。如下圖所示,在建構目标表時,定義了blackhole_pv_uv表,構造了一個無實際存儲的目标端,充當調試作用,先把邏輯跑通,然後再去往目标端去寫代碼。Blackhole 會吸收掉輸出結果資料,先處理掉源端和計算的問題。
以上的表會落到 Flink Catalog裡,對于實時計算pv/uv上下遊表格的準備就完成了。如果需要調整表,也可以通過DDL SQL語句完成。
做好建表準備後,如何實時計算想要達到的目标呢?以最簡單的方式來示範。
先把資料寫到Blackhole裡,然後把4個字段值計算出來,比如cuurenttime,event_hour等。
通過上圖所示的代碼可以計算出,資料是什麼時候輸入的,資料的pv/uv值等等。
運作剛剛寫入的作業:
然後點選建立SQL作業,
建立完成後,點選啟動。
啟動後可以點選 Flink UI 來檢視運作狀态。檢視時候可以看到下端有顯示記錄了8條資料:
回到資料庫也能看到對應的8條資料:
如何把實際的結果寫到holo裡呢?
核心邏輯與上文實時計算的邏輯是一樣的,唯一不一樣的是,要把計算的結果既輸出到holo_pv_uv裡去,同時也輸出到backhole裡去,也就是要把同樣的結果輸出兩份,這是在流計算裡經常會遇到的情況。甚至還有在同一作業裡不同的業務邏輯或計算結果,也要輸出到不同的目标端的情況。
打開實時計算 Flink 頁面的SQL編輯器,在輸入框中建立 temporary view,把資料記錄到blackhole 裡和holo裡。
為了實作這個目标,需要增加一個叫begin statement set和end的文法,這其實是定義了一個計算邏輯,使得在它們中間的邏輯任務就會同時運作。
然後完成部署、建立作業和啟動後,就能看到這個計算邏輯已經成功了。