<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入解讀 Flink SQL 1.13

          共 7946字,需瀏覽 16分鐘

           ·

          2021-06-27 13:57

          一、Flink SQL 1.13 概覽





          Flink 1.13 是一個(gè)社區(qū)大版本,解決的 issue 在 1000 個(gè)以上,通過上圖我們可以看到,解決的問題大部分是關(guān)于 Table/SQL 模塊,一共 400 多個(gè) issue 占了總體的 37% 左右。這些 issue 主要圍繞了 5 個(gè) FLIP 展開,在本文中我們也會(huì)根據(jù)這 5 個(gè)方面進(jìn)行介紹,它們分別是:




          下面我們對這些 FLIP 進(jìn)行詳細(xì)解讀。


          二、 核心 feature 解讀



          1. FLIP-145:支持 Window TVF



          社區(qū)的小伙伴應(yīng)該了解,在騰訊、阿里巴巴、字節(jié)跳動(dòng)等公司的內(nèi)部分支已經(jīng)開發(fā)了這個(gè)功能的基礎(chǔ)版本。這次 Flink 社區(qū)也在 Flink 1.13 推出了 TVF 的相關(guān)支持和優(yōu)化。下面將從 Window TVF 語法、近實(shí)時(shí)累計(jì)計(jì)算場景、 Window 性能優(yōu)化、多維數(shù)據(jù)分析,來解讀這個(gè)新功能。





          ■ 1.1 Window TVF 語法



          在 1.13 版本前,window 的實(shí)現(xiàn)是通過一個(gè)特殊的 SqlGroupedWindowFunction:


          SELECT   TUMBLE_START(bidtime,INTERVAL '10' MINUTE),  TUMBLE_END(bidtime,INTERVAL '10' MINUTE),  TUMBLE_ROWTIME(bidtime,INTERVAL '10' MINUTE),  SUM(price)FROM MyTableGROUP BY TUMBLE(bidtime,INTERVAL '10' MINUTE)


          在 1.13 版本中,我們對它進(jìn)行了 Table-Valued Function 的語法標(biāo)準(zhǔn)化:


          SELECT WINDOW_start,WINDOW_end,WINDOW_time,SUM(price) FROM Table(TUMBLE(Table myTable,DESCRIPTOR(biztime),INTERVAL '10' MINUTE))GROUP BY WINDOW_start,WINDOW_end


          通過對比兩種語法,我們可以發(fā)現(xiàn):TVF 語法更加靈活,不需要必須跟在 GROUP BY 關(guān)鍵字后面,同時(shí) Window TVF 基于關(guān)系代數(shù),使得其更加標(biāo)準(zhǔn)。在只需要?jiǎng)澐执翱趫鼍皶r(shí),可以只用 TVF,無需用 GROUP BY 做聚合,這使得 TVF 擴(kuò)展性和表達(dá)能力更強(qiáng),支持自定義 TVF(例如實(shí)現(xiàn) TOP-N 的 TVF)。




          上圖中的示例就是利用 TVF 做的滾動(dòng)窗口的劃分,只需要把數(shù)據(jù)劃分到窗口,無需聚合;如果后續(xù)需要聚合,再進(jìn)行 GROP BY 即可。同時(shí),對于熟悉批 SQL 的用戶來說,這種操作是非常自然的,我們不再需要像 1.13 版本之前那樣必須要用特殊的 SqlGroupedWindowFunction 將窗口劃分和聚合綁定在一起。

          目前 Window TVF 支持 tumble window,hop window,新增了 cumulate window;session window 預(yù)計(jì)在 1.14 版本也會(huì)支持。


          ■ 1.2 Cumulate Window




          Cumulate window 就是累計(jì)窗口,簡單來說,以上圖里面時(shí)間軸上的一個(gè)區(qū)間為窗口步長。


          • 第一個(gè) window 統(tǒng)計(jì)的是一個(gè)區(qū)間的數(shù)據(jù);

          • 第二個(gè) window 統(tǒng)計(jì)的是第一區(qū)間和第二個(gè)區(qū)間的數(shù)據(jù);

          • 第三個(gè) window 統(tǒng)計(jì)的是第一區(qū)間,第二個(gè)區(qū)間和第三個(gè)區(qū)間的數(shù)據(jù)。



          累積計(jì)算在業(yè)務(wù)場景中非常常見,如累積 UV 場景。在 UV 大盤曲線中:我們每隔 10 分鐘統(tǒng)計(jì)一次當(dāng)天累積用戶 UV。




          在 1.13 版本之前,當(dāng)需要做這種計(jì)算時(shí),我們一般的 SQL 寫法如下:


          INSERT INTO cumulative_UVSELECT date_str,MAX(time_str),COUNT(DISTINCT user_id) as UVFROM (  SELECT    DATE_FORMAT(ts,'yyyy-MM-dd') as date_str,    SUBSTR(DATE_FORMAT(ts,'HH:mm'),1,4) || '0' as time_str,  user_id  FROM user_behavior)GROUP BY date_str


          先將每條記錄所屬的時(shí)間窗口字段拼接好,然后再對所有記錄按照拼接好的時(shí)間窗口字段,通過 GROUP BY 做聚合,從而達(dá)到近似累積計(jì)算的效果。


          • 1.13 版本前的寫法有很多缺點(diǎn),首先這個(gè)聚合操作是每條記錄都會(huì)計(jì)算一次。其次,在追逆數(shù)據(jù)的時(shí)候,消費(fèi)堆積的數(shù)據(jù)時(shí),UV 大盤的曲線就會(huì)跳變。

          • 在 1.13 版本支持了 TVF 寫法,基于 cumulate window,我們可以修改為下面的寫法,將每條數(shù)據(jù)按照 Event Time 精確地分到每個(gè) Window 里面, 每個(gè)窗口的計(jì)算通過 watermark 觸發(fā),即使在追數(shù)據(jù)場景中也不會(huì)跳變。


          INSERT INTO cumulative_UVSELECT WINDOW_end,COUNT(DISTINCT user_id) as UVFROM Table(  CUMULATE(Table user_behavior,DESCRIPTOR(ts),INTERVAL '10' MINUTES,INTERVAL '1' DAY)))GROUP BY WINDOW_start,WINDOW_end


          UV 大盤曲線效果如下圖所示:




          ■ 1.3 Window 性能優(yōu)化



          Flink 1.13 社區(qū)開發(fā)者們對 Window TVF 進(jìn)行了一系列的性能優(yōu)化,包括:


          • 內(nèi)存優(yōu)化:通過內(nèi)存預(yù)分配,緩存 window 的數(shù)據(jù),通過 window watermark 觸發(fā)計(jì)算,通過申請一些內(nèi)存 buffer 避免高頻的訪問 state;

          • 切片優(yōu)化:將 window 切片,盡可能復(fù)用已計(jì)算結(jié)果,如 hop window,cumulate window。計(jì)算過的分片數(shù)據(jù)無需再次計(jì)算,只需對切片的計(jì)算結(jié)果進(jìn)行復(fù)用;

          • 算子優(yōu)化:window 算子支持 local-global 優(yōu)化;同時(shí)支持 count(distinct) 自動(dòng)解熱點(diǎn)優(yōu)化;

          • 遲到數(shù)據(jù):支持將遲到數(shù)據(jù)計(jì)算到后續(xù)分片,保證數(shù)據(jù)準(zhǔn)確性。





          基于這些優(yōu)化,我們通過開源 Benchmark (Nexmark) 進(jìn)行性能測試。結(jié)果顯示 window 的普適性能有 2x 提升,且在 count(distinct) 場景會(huì)有更好的性能提升。





          ■ 1.4 多維數(shù)據(jù)分析



          語法的標(biāo)準(zhǔn)化帶來了更多的靈活性和擴(kuò)展性,用戶可以直接在 window 窗口函數(shù)上進(jìn)行多維分析。如下圖所示,可以直接進(jìn)行 GROUPING SETS、ROLLUP、CUBE 的分析計(jì)算。如果是在 1.13 之前的版本,我們可能需要對這些分組進(jìn)行單獨(dú)的 SQL 聚合,再對聚合結(jié)果做 union 操作才能達(dá)到類似的效果。而現(xiàn)在,類似這種多維分析的場景,可以直接在 window TVF 上支持。




          支持 Window Top-N

          除了多維分析,Window TVF 也支持 Top-N 語法,使得在 Window 上取 Top-N 的寫法更加簡單。




          2. FLIP-162:時(shí)區(qū)和時(shí)間函數(shù)


          ■ 2.1 時(shí)區(qū)問題分析



          大家在使用 Flink SQL 時(shí)反饋了很多時(shí)區(qū)相關(guān)的問題,造成時(shí)區(qū)問題的原因可以歸納為 3 個(gè):


          • PROCTIME() 函數(shù)應(yīng)該考慮時(shí)區(qū),但未考慮時(shí)區(qū);

          • CURRENT_TIMESTAMP/CURRENT_TIME/CURRENT_DATE/NOW() 函數(shù)未考慮時(shí)區(qū);

          • Flink 的時(shí)間屬性,只支持定義在 TIMESTAMP 這種數(shù)據(jù)類型上面,這個(gè)類型是無時(shí)區(qū)的,TIMESTAMP 類型不考慮時(shí)區(qū),但用戶希望是本地時(shí)區(qū)的時(shí)間。






          針對 TIMESTAMP 類型沒有考慮時(shí)區(qū)的問題,我們提議通過 TIMESTAMP_LTZ 類型支持 (TIMESTAMP_LTZ 是 timestamp with local time zone 的縮寫)。可以通過下面的表格來進(jìn)行和 TIMESTAMP 的對比:




          TIMESTAMP_LTZ 區(qū)別于之前我們使用的 TIMESTAMP,它表示絕對時(shí)間的含義。通過對比我們可以發(fā)現(xiàn):


          • 如果我們配置使用 TIMESTAMP,它可以是字符串類型的。用戶不管是從英國還是中國時(shí)區(qū)來觀察,這個(gè)值都是一樣的;

          • 但是對于 TIMSTAMP_TLZ 來說,它的來源就是一個(gè) Long 值,表示從時(shí)間原點(diǎn)流逝過的時(shí)間。同一時(shí)刻,從時(shí)間原點(diǎn)流逝的時(shí)間在所有時(shí)區(qū)都是相同的,所以這個(gè) Long 值是絕對時(shí)間的概念。當(dāng)我們在不同的時(shí)區(qū)去觀察這個(gè)值,我們會(huì)用本地的時(shí)區(qū)去解釋成 “年-月-日-時(shí)-分-秒” 的可讀格式,這就是 TIMSTAMP_TLZ 類型,TIMESTAMP_LTZ 類型也更加符合用戶在不同時(shí)區(qū)下的使用習(xí)慣。


          下面的例子展示了 TIMESTAMP 和 TIMESTAMP_LTZ 兩個(gè)類型的區(qū)別。



          ■ 2.2 時(shí)間函數(shù)糾正


          訂正 PROCTIME() 函數(shù)




          當(dāng)我們有了 TIMESTAMP_LTZ 這個(gè)類型的時(shí)候,我們對 PROCTIME() 類型做了糾正:


          • 在 1.13 版本之前,它總是返回 UTC 的 TIMESTAMP;

          • 而現(xiàn)在,我們把返回類型變?yōu)榱?TIMESTAMP_LTZ。


          PROCTIME 除了表示函數(shù)之外,也可以表示時(shí)間屬性的標(biāo)記。


          訂正 CURRENT_TIMESTAMP/CURRENT_TIME/CURRENT_DATE/NOW() 函數(shù)

          這些函數(shù)在不同時(shí)區(qū)下出來的值是會(huì)發(fā)生變化的。例如在英國 UTC 時(shí)區(qū)時(shí)候是凌晨 2 點(diǎn);但是如果你設(shè)置了時(shí)區(qū)是 UTC+8,時(shí)間就是在早上的 10 點(diǎn)。不同時(shí)區(qū)的實(shí)際時(shí)間會(huì)發(fā)生變化,效果如下圖:



          解決 processing time Window 時(shí)區(qū)問題

          大家都知道 proctime 可以表示一個(gè)時(shí)間屬性,對 proctime 的 window 操作:

          • 在 1.13 版本之前,如果我們需要做按天的 window 操作,你需要手動(dòng)解決時(shí)區(qū)問題,去做一些 8 小時(shí)的偏移然后再減回去;

          • 在 FLIP-162 中我們解決了這個(gè)問題,現(xiàn)在用戶使用的時(shí)候十分簡單,只需要聲明 proctime 屬性,因?yàn)?PROCTIME() 函數(shù)的返回值是TIMESTAMP_LTZ,所以結(jié)果是會(huì)考慮本地的時(shí)區(qū)。下圖的例子顯示了在不同的時(shí)區(qū)下,proctime 屬性的 window 的聚合是按照本地時(shí)區(qū)進(jìn)行的。



          訂正 Streaming 和 Batch 模式下函數(shù)取值方式

          時(shí)間函數(shù)其實(shí)在流和批上面的表現(xiàn)形式會(huì)有所區(qū)別,這次修正主要是讓其更加符合用戶實(shí)際的使用習(xí)慣。例如以下函數(shù):


          • 在流模式中是 per-record 計(jì)算,即每條數(shù)據(jù)都計(jì)算一次;

          • 在 Batch 模式是 query-start 計(jì)算,即在作業(yè)開始前計(jì)算一次。例如我們常用的一些 Batch 計(jì)算引擎,如 Hive 也是在每一個(gè)批開始前計(jì)算一次。




          ■ 2.3 時(shí)間類型使用


          在 1.13 版本也支持了在 TIMESTAMP 列上定義 Event time,也就是說 Event time 現(xiàn)在既支持定義在 TIMESTAMP 列上,也支持定義在 TIMESTAMP_ LTZ 列上。那么作為用戶,具體什么場景用什么類型呢?


          • 當(dāng)作業(yè)的上游源數(shù)據(jù)包含了字符串的時(shí)間(如:2021-4-15 14:00:00)這樣的場景,直接聲明為 TIMESTAMP 然后把 Event time 定義在上面即可,窗口在計(jì)算的時(shí)候會(huì)基于時(shí)間字符串進(jìn)行切分,最終會(huì)計(jì)算出符合你實(shí)際想要的預(yù)想結(jié)果;



          • 當(dāng)上游數(shù)據(jù)源的打點(diǎn)時(shí)間屬于 long 值,表示的是一個(gè)絕對時(shí)間的含義。在 1.13 版本你可以把 Event time 定義在 TIMESTAMP_LTZ 上面。此時(shí)定義在 TIMESTAMP_LTZ 類型上的各種 WINDOW 聚合,都能夠自動(dòng)的解決 8 小時(shí)的時(shí)區(qū)偏移問題,無需按照之前的 SQL 寫法額外做時(shí)區(qū)的修改和訂正。





          小提示:Flink SQL 中關(guān)于時(shí)間函數(shù),時(shí)區(qū)支持的這些提升,是版本不兼容的。用戶在進(jìn)行版本更新的時(shí)候需要留意作業(yè)邏輯中是否包含此類函數(shù),避免升級后業(yè)務(wù)受到影響。


          ■ 2.4 夏令時(shí)支持




          在 Flink 1.13 以前,對于國外夏令時(shí)時(shí)區(qū)的用戶,做窗口相關(guān)的計(jì)算操作是十分困難的一件事,因?yàn)榇嬖谙牧顣r(shí)和冬令時(shí)切換的跳變。

          Flink 1.13 通過支持在 TIMESTAMP_LTZ 列上定義時(shí)間屬性,同時(shí) Flink SQL 在 WINDOW 處理時(shí)巧妙地結(jié)合 TIMESTAMP 和 TIMESTAMP_LTZ 類型,優(yōu)雅地支持了夏令時(shí)。這對國外夏令時(shí)時(shí)區(qū)用戶,以及有海外業(yè)務(wù)場景的公司比較有用。

          三、重要改進(jìn)解讀



          1. FLIP-152:提升 Hive 語法兼容性



          FLIP-152 主要是做了 Hive 語法的兼容性增強(qiáng),支持了 Hive 的一些常用 DML 和 DQL 語法,包括:




          通過 Hive dialect 支持 Hive 常用語法。Hive 有很多的內(nèi)置函數(shù),Hive dialect 需要配合 HiveCatalog 和 Hive Module 一起使用,Hive Module 提供了 Hive 所有內(nèi)置函數(shù),加載后可以直接訪問。




          與此同時(shí),我們還可以通過 Hive dialect 創(chuàng)建/刪除 Catalog 函數(shù)以及一些自定義的函數(shù),這樣使得 Flink SQL 與 Hive 的兼容性得到了極大的提升,讓熟悉 Hive 的用戶使用起來會(huì)更加方便。





          2. FLIP-163:改進(jìn) SQL Client



          在 1.13 版本之前,大家覺得 Flink SQL Client 就是周邊的一個(gè)小工具。但是,F(xiàn)LIP-163 在 1.13 版本進(jìn)行了重要改進(jìn):




          1. 通過 -i 的參數(shù),提前把 DDL 一次性加載初始化,方便初始化表的多個(gè) DDL 語句,不需要多次執(zhí)行命令創(chuàng)建表,替代了之前用 yaml 文件方式創(chuàng)建表;

          2.支持 -f 參數(shù),其中 SQL 文件支持 DML(insert into)語句;

          3. 支持更多實(shí)用的配置:




            • 通過 SET SQL-client.verbose = true , 開啟 verbose,通過開啟 verbose 打印整個(gè)信息,相對以前只輸出一句話更加容易追蹤錯(cuò)誤信息;
            • 通過 SET execution.runtime-mode=streaming / batch 支持設(shè)置批/流作業(yè)模式;
            • 通過 SET pipline.name=my_Flink_job 設(shè)置作業(yè)名稱;
            • 通過 SET execution.savepoint.path=/tmp/Flink-savepoints/savepoint-bb0dab 設(shè)置作業(yè) savepoint 路徑;
            • 對于有依賴的多個(gè)作業(yè),通過 SET Table.dml-sync=true 去選擇是否異步執(zhí)行,例如離線作業(yè),作業(yè) a 跑完才能跑作業(yè) b,通過設(shè)置為 true 實(shí)現(xiàn)執(zhí)行有依賴關(guān)系的 pipeline 調(diào)度。


          4. 同時(shí)支持 STATEMENT SET語法:





          有可能我們的一個(gè)查詢不止寫到一個(gè) sink 里面,而是需要輸出到多個(gè) sink,比如一個(gè) sink 寫到 jdbc,一個(gè) sink 寫到 HBase。


            • 在 1.13 版本之前需要啟動(dòng) 2 個(gè) query 去完成這個(gè)作業(yè);
            • 在 1.13 版本,我們可以把這些放到一個(gè) statement 里面,以一個(gè)作業(yè)的方式去執(zhí)行,能夠?qū)崿F(xiàn)節(jié)點(diǎn)的復(fù)用,節(jié)約資源。



          3. FLIP-136:增強(qiáng) DataStream 和 Table 的轉(zhuǎn)換


          雖然 Flink SQL 大大降低了我們使用實(shí)時(shí)計(jì)算的一些使用門檻,但 Table/SQL 這種高級封裝也屏蔽了一些底層實(shí)現(xiàn),如 timer,state 等。不少高級用戶希望能夠直接操作 DataStream 獲得更多的靈活性,這就需要在 Table 和 DataStream 之間進(jìn)行轉(zhuǎn)換。FLIP-136 增強(qiáng)了 Table 和 DataStream 間的轉(zhuǎn)換,使得用戶在兩者之間的轉(zhuǎn)換更加容易。


          • 支持 DataStream 和 Table 轉(zhuǎn)換時(shí)傳遞 EVENT TIME 和 WATERMARK;

          Table Table = TableEnv.fromDataStream(  dataStream,  Schema.newBuilder()  .columnByMetadata("rowtime","TIMESTMP(3)")  .watermark("rowtime","SOURCE_WATERMARK()")  .build());)

          • 支持 Changelog 數(shù)據(jù)流在 Table 和 DataStream 間相互轉(zhuǎn)換。


          //DATASTREAM 轉(zhuǎn) TableStreamTableEnvironment.fromChangelogStream(DataStream<ROW>): TableStreamTableEnvironment.fromChangelogStream(DataStream<ROW>,Schema): Table//Table 轉(zhuǎn) DATASTREAMStreamTableEnvironment.toChangelogStream(Table): DataStream<ROW>StreamTableEnvironment.toChangelogStream(Table,Schema): DataStream<ROW>  


          四、Flink SQL 1.14 未來規(guī)劃



          1.14 版本主要有以下幾點(diǎn)規(guī)劃:


          • 刪除 Legacy Planner:從 Flink 1.9 開始,在阿里貢獻(xiàn)了 Blink-Planner 之后,很多一些新的 Feature 已經(jīng)基于此 Blink Planner 進(jìn)行開發(fā),以前舊的 Legacy Planner 會(huì)徹底刪除;

          • 完善 Window TVF:支持 session window,支持 window TVF 的 allow -lateness 等;

          • 提升 Schema Handling:全鏈路的 Schema 處理能力以及關(guān)鍵校驗(yàn)的提升;

          • 增強(qiáng) Flink CDC 支持:增強(qiáng)對上游 CDC 系統(tǒng)的集成能力,F(xiàn)link SQL 內(nèi)更多的算子支持 CDC 數(shù)據(jù)流。


          五、總結(jié)



          本文詳細(xì)解讀了 Flink SQL 1.13 的核心功能和重要改進(jìn)。


          • 支持 Window TVF;

          • 系統(tǒng)地解決時(shí)區(qū)和時(shí)間函數(shù)問題;

          • 提升 Hive 和 Flink 的兼容性;

          • 改進(jìn) SQL Client;

          • 增強(qiáng) DataStream 和 Table 的轉(zhuǎn)換。



          同時(shí)還分享了社區(qū)關(guān)于 Flink SQL 1.14 的未來規(guī)劃,相信看完文章的同學(xué)可以對 Flink SQL 在這個(gè)版本中的變化有更多的了解,在實(shí)踐過程中大家可以多多關(guān)注這些新的改動(dòng)和變化,感受它們所帶來的業(yè)務(wù)層面上的便捷。
          瀏覽 70
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成视频| 又爽又黄无遮挡网站 | 欧美久久久| 久久机热 | 激情乱伦图片 |