天天看點

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

作為一家創新驅動的科技公司,袋鼠雲每年研發投入達數千萬,公司80%員工都是技術人員,袋鼠雲産品家族包括企業級一站式資料中台PaaS數棧、互動式資料可視化大屏開發平台Easy[V]等産品也在迅速疊代。在進行産品研發的過程中,技術小哥哥們能文能武,不斷提升産品性能和體驗的同時,也把這些提升和優化過程記錄下來,現錄入“袋鼠雲研發手記”專欄中,以和業内童鞋們分享交流。

下為“袋鼠雲研發手記”專欄第三期,本期作者為袋鼠雲數棧引擎團隊。

袋鼠雲數棧引擎團隊

袋鼠雲數棧引擎團隊擁有多名專家級别,經驗豐富的後端開發工程師,分别支撐公司大數棧産品線的不同子項目的開發需求,從項目中提取并開源了FlinkX(基于Flink的資料同步),Jlogstash(logstash 的java 版本實作),FlinkStreamSQL(擴充原生FlinkSQL,實作流與維表的join)多個項目。

在長期的項目實踐與産品疊代過程中,團隊成員在 Hadoop技術棧上不斷深耕探索,積累了豐富的經驗與最佳實踐。

第三期

數棧·開源 拓展FlinkSQL實作流與維表的join

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

FlinkStreamSQL 已經開源在Github上 目前已獲380+Star

1、為什麼要擴充FlinkSQL?

實時計算需要完全SQL化

SQL是資料進行中使用最廣泛的語言。它允許使用者簡明扼要地聲明他們的業務邏輯。大資料批計算使用SQL很常見,但是支援SQL的實時計算并不多。其實,用SQL開發實時任務可以極大降低資料開發的門檻,在袋鼠雲數棧-實時計算子產品,我們決定實作完全SQL化。

**資料計算采用SQL的優勢

**

 聲明式。使用者隻需要表達我想要什麼,至于怎麼計算那是系統的事情,使用者不用關心。

 自動調優。查詢優化器可以為使用者的 SQL 生成最有的執行計劃。使用者不需要了解它,就能自動享受優化器帶來的性能提升。

 易于了解。很多不同行業不同領域的人都懂 SQL,SQL 的學習門檻很低,用 SQL 作為跨團隊的開發語言可以很大地提高效率。

 穩定。SQL 是一個擁有幾十年曆史的語言,是一個非常穩定的語言,很少有變動。是以當我們更新引擎的版本時,甚至替換成另一個引擎,都可以做到相容地、平滑地更新。

實時計算還需要流與維表的JOIN

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

在實時計算的世界裡不隻是流與流的JOIN,還需要流與維表的JOIN

在實時計算的世界裡不隻是流與流的JOIN,還需要流與維表的JOIN。在去年,袋鼠雲數棧V3.0版本研發期間,當時最新版本——flink1.6中FlinkSQL,已經将SQL的優勢應用到Flink引擎中,但還未支援流與維表的JOIN。

關于FlinkSQL

FlinkSQL于2017年7月開始面向阿裡巴巴集團開放流計算服務的,雖然是一個非常年輕的産品,但是到雙11期間已經支撐了數千個作業,在雙11期間,Blink 作業的處理峰值達到了5+億每秒,而其中僅 Flink SQL 作業的處理總峰值就達到了3億/秒。

參考連結:

https://yq.aliyun.com/articles/457438

這裡先解釋下什麼是維表;維表是動态表,表裡所存儲的資料有可能不變,也有可能定時更新,但是更新頻率不是很頻繁。在業務開發中一般的維表資料存儲在關系型資料庫如mysql,oracle等,也可能存儲在hbase,redis等nosql資料庫。

2、是以要用FlinkSQL實作流與維表的join 分兩步:

一、用Flink api實作維表的功能

要實作維表功能就要用到 Flink Aysnc I/O 這個功能,是由阿裡巴巴貢獻給Apache Flink的。

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

Async I/O 是由阿裡巴巴貢獻給社群的,于1.2版本引入,主要目的是為了解決與外部系統互動時網絡延遲成為了系統瓶頸的問題。具體介紹可以看這篇文章:

http://wuchong.me/blog/2017/05/17/flink-internals-async-io/

對應到Flink 的api就是RichAsyncFunction 這個抽象類,繼層這個抽象類實作裡面的open(初始化),asyncInvoke(資料異步調用),close(停止的一些操作)方法,最主要的是實作asyncInvoke 裡面的方法。

流與維表的join會碰到兩個問題:

第一個是性能問題。因為流速要是很快,每一條資料都需要到維表做下join,但是維表的資料是存在第三方存儲系統,如果實時通路第三方存儲系統,不僅join的性能會差,每次都要走網絡io;還會給第三方存儲系統帶來很大的壓力,有可能會把第三方存儲系統搞挂掉。

是以解決的方法就是維表裡的資料要緩存,可以全量緩存,這個主要是維表資料不大的情況,還有一個是LRU緩存,維表資料量比較大的情況。

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

LRU維表的實作

第二個問題是流延遲過來的資料這麼跟之前的維表資料做關聯。這個就涉及到維表資料需要存儲快照資料,是以這樣的場景用HBase 做維表是比較适合的,因為HBase 是天生支援資料多版本的。

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

ALL維表的實作

二、解析流與維表join的SQL文法轉化成底層的FlinkAPI

因為FlinkSQL已經做了大部分SQL場景,我們不可能在去解析SQL的所有文法,在把他轉化成底層FlinkAPI。

是以我們做的就是解析SQL文法,來找到join表裡有沒有維表,如果有維表,那我們會把這個join的維表的語句單獨拆來,用Flink的TableAPI和StreamAPi 生成新DataStream,在把這個DataStream與其他的表在做join這樣就能用SQL來實作流與維表的join文法了。

SQL解析的工具就是用Apache calcite,Flink也是用這個架構做SQL解析的。是以所有文法都是可以解析的。

1. DEMO SQL

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

2. Calcite解析Insert into語句,拆分出子語句

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

**3. Calcite繼續解析select語句

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:
袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步:

Calcite繼續解析select語句

袋鼠雲研發手記 | 開源·數棧-擴充FlinkSQL實作流與維表的join1、為什麼要擴充FlinkSQL?2、是以要用FlinkSQL實作流與維表的join 分兩步: