Spark跟Flink的JDBC,都不靠譜
來源:安瑞哥是碼農
別誤會,這個不靠譜,說的是不論Spark還是Flink,都不能透過JDBC的方式,支援真正意義上的流式讀取,而不是它不可用。
至少,從目前這兩者的官方文件說明,或者透過我的親身實踐來看是這樣。
那麼下面,就來詳細聊聊,JDBC這種雖然具有普適性的資料庫連線方式,在流式讀取(或者說計算)中會存在哪些短板。
0. 資料來源的讀取分類
我們知道,隨著企業對資料處理的要求越來越高,這就直接導致我們的資料處理系統,對資料來源的讀取方式有著更加多變的要求。
對資料來源的讀取方式和頻率,從業務端的使用需求場景來看,大致可以分為兩大類:
第1種:為一次性的,即一次讀取完目標系統(比如資料庫)的所有資料,我們稱之為「批」處理;
第2種:連續性的,在第1種的基礎上,依然監控著資料來源端的變化,繼續讀取後續新增、變化的資料,我們稱之為「流」處理。
其中第1種,是我們對資料來源讀取的傳統要求,主流的計算引擎Spark和Flink都能滿足。
但對於第2種,雖然無論是Spark還是Flink這兩款計算引擎本身,都支援流式計算這個特性,但是這個支援其實有個重要的前提,那就是得資料來源端,以及跟資料來源端對應的對接方式配合才可以。
1. Spark的JDBC
之前我吹過牛逼,說但凡你能叫出名字的儲存系統,或者資料庫,Spark都有與之對應的介面,從而讀取到其中的資料,或者將計算後的結果儲存到其中。
誠然,Spark確實能做到這一點,但是,當我們想要用流的方式去讀取一些特定資料庫的資料來源時,它卻顯得有些力不從心了。
比如,我想讓它以流的方式去讀取mysql中的資料,咋整?
能想到的就是用它的structured streaming框架,來嘗試讀取mysql,但是呢,開啟官網一看它支援的資料來源(最新的),不免有點失落:
spark structured streaming支援的內建資料來源
也就是說,官方明確支援可以用流的方式讀取的資料來源中,是沒有mysql的,也沒有提到JDBC。
但是呢,之前的多次實踐經驗告訴我,有時候官方的話也不能全信,我們最好還是親自試驗一把,萬一可以呢,對吧。
根據以往的經驗,我寫出瞭如下的核心程式碼(記得提前在pom檔案中引入對應的mysql-connector包):
看起來好像是那麼回事,但是一執行起來你會發現:
我靠,果然不行,官網誠不欺我。
但我知道,Spark肯定是可以透過JDBC的方式讀取到mysql資料來源的。
於是,把核心程式碼改成這樣,就能跑通了:
只是這樣一來,就違背了我的初衷,這個邏輯就由原本我想要的「流計算」給硬生生改造成了「批處理」,也就說,這個修改之後的程式碼,它就不再是 Spark structured streaming 而是普通的 Spark。
所以說,Spark官方做不到(至少目前為止)直接用JDBC,以流的方式讀取資料來源。
在GitHub上看到一個開源專案,透過對官方原生支援的jdbc方式改造之後,說可以支援用Spark structured streaming來增量讀取mysql資料來源,我暫時沒有去驗證,有興趣的同學可以去看看。
地址為:
2. Flink的JDBC
開啟Flink的官網,在Flink connector一欄中赫然就出現了JDBC的身影(也沒有mysql):
那既然這樣,我們就來試試。
首先需要配置開發環境,跟Spark不一樣的是,Flink想要讀取mysql的資料來源,那需要引入flink特有的jdbc connector(非傳統的mysql-connector)。
注意這個版本的選擇,可能跟官網上描述的不一樣,最新官方文件的 version 由 connector 版本+Flink版本兩部分組成,而我這個版本稍微舊一點。
然後就是程式碼部分,如下(跟上面的Spark一樣,這裡只演示讀取mysql資料,然後列印出來):
package com.anryg.mysql.jdbc
import java.time.Duration
import org.apache.flink.contrib.streaming.state.EmbeddedRocksDBStateBackend
import org.apache.flink.streaming.api.CheckpointingMode
import org.apache.flink.streaming.api.environment.CheckpointConfig.ExternalizedCheckpointCleanup
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment
/**
* @DESC: 用JDBC方式讀取mysql資料來源
* @Auther: Anryg
* @Date: 2023/11/8 10:49
*/
object FromMysql2Print {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.enableCheckpointing(10000L)
env.setStateBackend(new EmbeddedRocksDBStateBackend(true)) //新的設定state backend的方式
env.getCheckpointConfig.setCheckpointStorage("hdfs://192.168.211.106:8020/tmp/flink_checkpoint/FromMysql2Print")
env.getCheckpointConfig.setExternalizedCheckpointCleanup(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION) //設定checkpoint記錄的保留策略
env.getCheckpointConfig.setAlignedCheckpointTimeout(Duration.ofMinutes(1L))
env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
val tableEnv = StreamTableEnvironment.create(env)
/**第一步:讀取mysql資料來源*/
tableEnv.executeSql(
"""
Create table data_from_mysql(
|`client_ip` STRING,
|`domain` STRING,
|`time` STRING,
|`target_ip` STRING,
|`rcode` int,
|`query_type` int,
|`authority_record` STRING,
|`add_msg` STRING,
|`dns_ip` STRING,
|PRIMARY KEY(`client_ip`,`domain`,`time`,`target_ip`,`rcode`,`query_type`) NOT ENFORCED
|)
|with(
|'connector' = 'jdbc',
|'url' = 'jdbc:mysql://192.168.221.173:3306/test',
| 'username' = '***',
| 'password' = '***',
| 'table-name' = 'test02' //確定文字資料來源的分隔符
|)
""".stripMargin)
/**結果直接列印*/
tableEnv.executeSql(
"""
|select * from data_from_mysql limit 100
""".stripMargin).print()
}
}
整個程式碼內容,跟上篇文章寫的CDC方式讀取mysql非常相似(有興趣可以去看我的上篇文章對比一下)。
但是呢,把它執行起來之後,當程式把目前這張表的資料讀取完,就會戛然而止:
也就說,雖然我們用的是Flink流式計算的上下文(StreamExecutionEnvironment),但是,因為程式用的JDBC方式讀取資料來源,所以,它依然只能以批處理的方式執行。
在這點上,Flink跟Spark的表現是一毛一樣的。
最後
透過上面的驗證可以確定,不管是Spark還是Flink,想要以JDBC的方式來流式讀取mysql資料來源(或者其他資料庫)是行不通的,至少,直接用官方提供的「正規軍」方式是不行的。
那麼,對於想直接透過計算引擎,去讀取某些資料庫(比如mysql)的增量資料,好像當下的最優解決方案只有Flink CDC了。
當然,JDBC也並不是一無是處,對於一些低版本的資料庫(CDC暫時不支援的),比如mysql5.5及以下版本的歷史資料匯入,它還是能派上用場的。
對吧。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027827/viewspace-2994901/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 無人值守的運維到底靠譜不靠譜?運維
- 聊聊flink jdbc的ParameterValuesProviderJDBCIDE
- 很多賺積分的方法並不靠譜
- 架構思考:不靠譜的元件與可靠的系統架構元件
- Spark Streaming VS FlinkSpark
- Spark Streaming和Flink的區別Spark
- TipsWorks與《帕斯卡契約》:從“不靠譜”到100萬
- 大資料框架對比 - Hadoop、Spark、Storm、Samza、Spark、Flink大資料框架HadoopSparkORM
- 從專業的角度來看,遊戲中的兵刃格鬥靠不靠譜?遊戲
- 學web前端開發,看視訊自學到底靠譜不靠譜,看完你來說!Web前端
- 為什麼諸多頂級期刊論文中的觀點也不靠譜?
- 奇思妙想:用遊戲來做城市規劃靠不靠譜?遊戲
- 將全景分割用到養豬場,AI養豬到底靠不靠譜?AI
- 抱歉,我覺得程式設計師副業賺錢並不靠譜程式設計師
- 搶票軟體不靠譜?不如看看用AI怎麼玩轉12306AI
- spark:自定義分割槽,自定義排序,spark與jdbc,廣播變數等Spark排序JDBC變數
- Paimon 跟 Spark 是否也能玩得來AISpark
- 不靠畫面拼節奏:用聽覺驅動遊戲,靠譜嗎?遊戲
- Angular 6 + 折騰記 :(11) 寫一個挺不靠譜的多少秒/分/時/天前的管道Angular
- Apache 流框架 Flink,Spark Streaming,Storm對比分析(1)Apache框架SparkORM
- Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)Apache框架SparkORM
- Apache 流框架 Flink,Spark Streaming,Storm對比分析(一)Apache框架SparkORM
- Apache 流框架 Flink,Spark Streaming,Storm對比分析(二)Apache框架SparkORM
- 新技術到底靠不靠譜?在中國用一下就知道了
- JS不靠譜系列: 寫一個驗證過期時間的函式,包含jest單元測試JS函式
- EBC金融外匯平臺怎麼樣正規嗎,外匯投資靠不靠譜?
- Spark SQL:JDBC資料來源複雜綜合案例實戰SparkSQLJDBC
- Flink流批一體是否能真正取代Spark引擎Spark
- 日本分析機構不看好PS5市場前景,原因是“白色曲面外形不靠譜”
- 小特性 大用途 —— YashanDB JDBC驅動的這些特性你都get了嗎?JDBC
- Linux跟Windows一樣,都需要防毒軟體嗎?LinuxWindows防毒
- 實時計算框架特點及對比:Flink、Spark Streaming、Storm框架SparkORM
- Spark Streaming,Flink,Storm,Kafka Streams,Samza:如何選擇流處理框架SparkORMKafka框架
- 槓上Spark、Flink?Kafka為何轉型流資料平臺SparkKafka
- 槓上 Spark、Flink?Kafka 為何轉型流資料平臺SparkKafka
- 永久免費oa辦公系統到底靠不靠譜?免費oa辦公系統市場分析
- 開源專案推薦 - 巨鯨任務排程平臺(Spark、Flink)Spark
- [Flink] Flink 版本特性的演進