伍翀 :大資料實時計算Flink SQL解密
【IT168 專稿】本文根據伍翀老師在2018年5月12日【第九屆中國資料庫技術大會】現場演講內容整理而成。
講師簡介:
伍翀,阿里巴巴高階研發工程師,花名“雲邪”,阿里巴巴計算平臺事業部高階研發工程師,Apache Flink Committer。北京理工大學碩士畢業,2015 年加入阿里巴巴,參與阿里巴巴實時計算引擎 JStorm 的開發與設計。從 2016 年開始從事阿里新一代實時計算引擎 Blink SQL 的開發與最佳化。現在專注的方向主要是分散式處理和實時計算,熱愛開源,熱愛分享。
摘要:
SQL是資料處理中使用最廣泛的語言。它允許使用者簡明扼要地宣告他們的業務邏輯。大資料批計算使用SQL很常見,但是支援SQL的實時計算並不多。Apache Flink是一款同時支援批和流計算的引擎,Flink SQL的實現完全遵循ANSI SQL標準,這是它和其他流處理框架(例如Kafka和Spark)在DSL上的一個重要的不同。阿里巴巴是Flink SQL最大的貢獻者,Flink開源社群的一半以上的SQL功能都是阿里工程師開發的。阿里內部絕大部分的流計算業務也都在使用Flink SQL編寫。本次演講我們將介紹Flink SQL的設計原理以及分享在阿里大規模使用中收穫的經驗。
分享大綱:
1、Background
2、Flink SQL基本概念
3、Flink SQL核心功能
4、Flink SQL最佳化
5、阿里雲流計算產品
正文:
阿里巴巴自2015年開始調研開源流計算引擎,最終決定基於Flink打造新一代計算引擎,針對Flink存在的不足進行最佳化和改進,並將最終程式碼貢獻給開源社群。目前為止,我們已經向社群貢獻了數百個Commiter。阿里巴巴將該專案命名為Blink,主要由Blink Runtime與Flink SQL組成。Blink Runtime是阿里巴巴內部高度定製化的計算核心,Flink SQL則是面向使用者的API層,我們完善了部分功能,比如Agg、Join、Windows處理等。今年,我們已經全部跑通TPCH 及TPC-DS的Query,熟悉資料庫的人都知道,這代表著整個資料庫或引擎是一個基本功能完備的產品。
接下來主要介紹Flink SQL的基本概念及使用。傳統的流式計算引擎,比如Storm、Spark Streaming都會提供一些function或者datastream API,使用者透過Java或Scala寫業務邏輯,這種方式雖然靈活,但有一些不足,比如具備一定門檻且調優較難,隨著版本的不斷更新,API也出現了很多不相容的地方。
我們一直在思考最適合流計算處理的API,毫無疑問,SQL已經成為大資料領域通用且成熟的語言,因此我們的Flink和Blink均基於此,之所以選擇將SQL作為核心API,是因為其具有幾個非常重要的特點,一是SQL屬於設定式語言,使用者只要表達清楚需求即可,不需要了解具體做法;二是SQL可最佳化,內建多種查詢最佳化器,這些查詢最佳化器可為SQL翻譯出最優執行計劃;三是SQL易於理解,不同行業和領域的人都懂;四是SQL非常穩定,在資料庫30多年的歷史中,SQL本身變化較少,非常穩定。當我們升級或替換引擎時,使用者是無感知的且完全相容;最後,SQL經過最佳化可以統一流和批。
過去,我們既需要批模式跑全量資料,也需要流模式實時跑增量資料,因此需要同時維護兩個引擎,並且保持兩份程式碼之間的同步。如果使用SQL,我們便可以一份程式碼同時跑在兩個模式下,但SQL是為傳統批處理設計的,並不能為流處理所用。SQL定義在表上,而不是流上。傳統SQL處理的資料集比較有限,查詢一次只返回一個結果。但是,流處理需要不斷接收資料,不斷對結果進行更新,並且查詢也不會結束,這導致其需要對歷史資料不斷修正。所以,SQL的很多概念無法直接對映到流計算,這就是在流計算上定義SQL的難點。
為了在流計算上定義SQL,我們需要引入幾個概念。既然批處理需要定義SQL表的概念,那在流計算上也需要表的概念,我們需要將傳統靜態表擴充套件成動態表,所謂動態表就是資料會隨時間而不斷變化的表。此時,我們發現流和動態表之間有一種對偶性,也就是說流和動態表可以相互轉換。將流的每條資料插入到資料庫中,就得到了一張表;同時我們可以抽取動態表的changelog還原原始流。
從流計算到SQL,我們可以把它看成是連續查詢。連續查詢區別於傳統的批處理查詢,需要源源不斷地接收資料,每收到一條新資料就會更新結果且結果也是一張動態表,那結果的動態表又可以作為下一個查詢的輸入,從而串起整個流計算。
基於上述兩個概念,我們可以在SQL上定義流計算。但是,流計算中的資料需要不斷修正和更新,因此這些資料下發後可能導致最終結果的錯誤,我們需要把這些錯誤資料進行修正,這就涉及到流計算中一個非常重要的概念——Retraction。
為了解釋此概念,我們舉一個簡單的例子,上圖所示有一個點選輸入流,它具備兩個欄位:user和url,經過第一個查詢根據使用者進行分組,統計每個使用者的點選次數;進入第二個查詢,根據點選次數進行分組,統計每個次數的具體點選人數。最終,我們會收到兩條記錄,點選次數所對應的人數。從結果明顯可以看出計算有誤,Mary的資料並沒有合併計數,這就需要引入修正的概念。
如上圖所示,經過修正之後,經過第二個查詢時,Mary的總查詢次數會被合併計算,Mary 1的結果會被告知撤回,從而輸出正確的結果,這就是引入Retraction的作用。在整個過程中,是否觸發Retraction以及傳送方式均由最佳化器決定,使用者對整個過程是無感知的。
在此基礎上,我們發現世界不需要所謂的Stream SQL語法,標準的ANSI SQL就可用來定義流計算,Flink SQL就是標準的ANSI SQL語法。其部分核心功能如下:DDL用來定義資料來源表、資料結構表;UDF、UDTF、UDAF使用者自定義函式,可以定製化使用者複雜的業務需求;JOIN是一個比較複雜的功能,包括流與流之間的Join,流與表之間的Join以及Windows Join等;聚合功能包括類似Group AGG,Windoes Agg以及Over Agg等。
接下來我會結合例項對核心功能進行介紹。首先是裝載資料,需要create table語法。如上圖所示,我們先定義一張clicks表,然後定義表的schema、user、cTime以及url,with裡是表的一系列屬性,它是一個來自kafka的日誌表,我們可以用SELECT * FROM clicks查詢轉載表裡面的資料。
如果要將上述查詢資料寫到某個表中,我們需要用create table定義結果表,語法同上,建立一張 last_clicks 結果表,主鍵是user,透過INSERT INTO 語法將上述查詢資料插入Mysql表中。
如果想把中間處理結果同時寫入多個儲存,比如把資料處理結果同時寫到Mysql和HBase,如上使用CREATE VIEW 定義一個來自淘寶的點選記錄,同時連續寫多個INSERT INTO到Mysql和HBase。
接下來是Group Aggregate,也就是無限流量聚合。所謂無限流量聚合指從歷史開始到現在的所有使用者點選資料,如上查詢展示的是根據使用者分組,然後統計點選次數。如果來了一條Mary1的資料,我們就先插入該資料,後續如果Mary再次進行點選,我們就在原資料基礎上進行修改更新,以此類推。
Window Aggregate是定義在視窗上的聚合,有別於上述無限流聚合,它的原理是是每個視窗對應輸出一個結果,比如每小時每個使用者的點選次數,需要在group by的結果上加上endT資料,也就是視窗標識。
接下來介紹雙流join,目前我們支援INNER, LEFT, RIGHT, FULL, SEMI, ANTI等Join型別,舉例說明雙流Join的主要使用場景,比如把主流打成寬表,並補上額外欄位等。如上圖所示,我們需要將訂單和物流表資訊進行Join操作,在Join的物理實現上會有兩份狀態,用來儲存兩條流到目前為止收到的所有歷史資料,淘汰機制時間設定為一天半一次。兩者中任何一方資訊延遲都會先在表中等待,直到同一個訂單的資訊與物流關聯之後才會透過Join輸出。
維表Join與雙流Join類似,目前支援INNER, LEFT兩種交易型別。維表Join的使用同樣為補全主流,但想補全的欄位在另一維表中。如上圖所示,使用時首先需要透過CREATE TABLE 語法定義一張維表,此處定義的是 Products 表,儲存與產品相關資訊,查詢同樣使用Join語法。Order與Products表透過Products ID實現Join。關鍵字PERIOD FOR SYSTEM_TIME 是 SQL 2.11標準裡的語法,意思是當前關聯的Products是當前時刻的資訊,關聯之後不再更新資訊。上圖右側展示的是維表Join物理執行的概念。我們可以根據Order去Products資料庫裡查詢資訊,最終Products維表返回關聯資訊。
核心功能如上所述,接下來主要聊最佳化。維表中,訂單O1查詢時是堵塞等待IO的狀態,此時無論如何調優效能,吞吐量和CPU使用率都上不去,因此我們引入非同步IO功能。
如上左半部分為未引入非同步IO時的狀態,如上右半部分為引入後,此時若發起A請求,不需等待IO就可立刻發起BCD查詢請求,然後非同步等待返回結果。返回ABCD以後再管理輸出,極大地提高了整體效能。
如上,非同步IO使用時與維表Join只有一行配置改動,對於使用者來說,這個使用是非常簡便的。
第二個最佳化是大資料中的常見場景——資料傾斜。如上為改進之前,紅色聚合節點出現資料積壓現象,而紫色節點相對較空。
如果持續一段時間,紅色聚合節點就會被打滿,從而變為熱點,所有上游map節點就會反壓,停止處理資料進入等待狀態,而下游的紫色節點基本處於空閒狀態。
我們引入Local-Global 聚合最佳化。左圖是未最佳化拓撲圖,右邊是引入Local-Global最佳化後的圖,我們在Map後引入Local Agg節點,Map與Local Agg是鏈在一起的一個執行緒,之間的資料傳輸沒有任何網路開銷。Local Agg可以將收到的資料按照 key進行預聚合,然後將結果按照 key分發給下游Global Agg進行彙總。
假如每個Map的 TPS 是每秒1萬的資料量,全域性就2個 key:紅色和紫色。如果 Local Agg聚合的間隔是每秒鐘一次,那麼每個Local Agg能將1萬條資料預聚合成最多2條(全域性共2個 key)。那麼Global Agg每秒鐘最多收到只會三條訊息,能有效降低Global Agg 的熱點。最佳化後,我們對此進行效能測試,發現Local-Global 可以帶來超過20倍的效能提升。因此,整個方案是十分有效的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31077337/viewspace-2213617/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 大資料“重磅炸彈”:實時計算框架 Flink大資料框架
- Storm 實戰:構建大資料實時計算ORM大資料
- Flink實時計算topN熱榜
- 實時計算Flink——產品安全
- 實時計算Flink效能調優
- Flink 在有贊實時計算的實踐
- 一文讀懂大資料實時計算大資料
- Flink大資料計算的機遇與挑戰大資料
- 實時計算Flink——快速入門概述
- 大資料開發實戰:實時資料平臺和流計算大資料
- 實時計算Flink>產品定價>計量計費
- Flink實時計算pv、uv的幾種方法
- 日常節省 30%計算資源:阿里雲實時計算 Flink 自動調優實踐阿里
- 實時計算無線資料分析
- Apache Flink 如何正確處理實時計算場景中的亂序資料Apache
- Apache Flink 在移動雲實時計算的實踐Apache
- 新一代大資料計算引擎 Flink從入門到實戰 (12) - flink 部署和作業提交大資料
- Arctic助力傳媒實現低成本的大資料準實時計算大資料
- 兩個例子(來自Storm實戰 構建大資料實時計算)ORM大資料
- 實時計算 Flink> 產品簡介——最新動態
- 實時計算Flink——獨享模式上下游配置模式
- 實時計算Flink——獨享模式系統架構模式架構
- 實時計算既有Flink,為何又推出個StreamPark?
- 【Flink】基於 Flink 的流式資料實時去重
- 大資料計算:結構化大資料計算的理想模式大資料模式
- 首批+唯一!阿里雲實時計算 Flink 版通過信通院大資料產品穩定性測試阿里大資料
- 端到端的實時計算:TiDB + Flink 最佳實踐TiDB
- 大資料計算生態之資料計算(二)大資料
- 大資料計算生態之資料計算(一)大資料
- 實時資料處理:Kafka 和 FlinkKafka
- Flink SQL 如何實現資料流的 Join?SQL
- Flink使用二次聚合實現TopN計算-亂序資料
- 大資料之亞秒級實時計算技術學哪些內容?大資料
- 百城匯杭州站大資料實時計算實戰專場圓滿落幕大資料
- 基於 Apache Flink 的實時計算資料流業務引擎在京東零售的實踐和落地Apache
- 雲端計算大資料面試題,雲端計算大資料面試題集錦大資料面試題
- flink sql 實時同步及離線同步SQL
- 雲端計算和大資料大資料