[離線計算-Spark|Hive] 數據近實時同步數倉方案設計

背景

最近閱讀了大量關於hudi相關文章, 下面結合對Hudi的調研, 設計一套技術方案用於支持 MySQL數據CDC同步至數倉中,避免繁瑣的ETL流程,藉助Hudi的upsert, delete 能力,來縮短數據的交付時間.

組件版本:

  • Hadoop 2.6.0
  • Hive 1.1.0
  • hudi 0.7.0
  • spark 2.4.6

架構設計

7NLAZ8.png

  1. 使用canal(阿里巴巴MySQL Binlog增量訂閱&消費組件)dump mysql binlog 數據
  2. 採集後將binlog 數據採集到kafka中, 按照庫名創建topic, 並按照表名將數據寫入topic 固定分區
  3. spark 消費數據將數據生成DF
  4. 將DF數據寫入hudi表
  5. 同步hudi元數據到hive中

寫入主要分成兩部分全量數據和增量數據:

  • 歷史數據通過bulkinsert 方式 同步寫入hudi

  • 增量數據直接消費寫入使用hudi的upsert能力,完成數據合併

寫入hudi在hdfs的格式如下:

7aCdJ0.png

hudi

hudi 如何處理binlog upsert,delete 事件進行數據的合併?

upsert好理解, 依賴本身的能力.

針對mysql binlog的delete 事件,使用記錄級別刪除:

  1. 需要在數據中添加 '_HOODIE_IS_DELETED' 且值爲true的列

  2. 需要在dataFrame中添加此列,如果此值爲false或者不存在則當作常規寫入記錄

如果此值爲true則爲刪除記錄

示例代碼如下:

StructField(_HOODIE_IS_DELETED, DataTypes.BooleanType, true, Metadata.empty());

dataFrame.write.format("org.apache.hudi")
               .option("hoodie.table.name", "test123")
               .option("hoodie.datasource.write.operation", "upsert")
               .option("hoodie.datasource.write.recordkey.field", "uuid")
               .option("hoodie.datasource.write.partitionpath.field", "partitionpath")
               .option("hoodie.datasource.write.storage.type", "COPY_ON_WRITE")
               .option("hoodie.datasource.write.precombine.field", "ts")
               .mode(Append)
               .save(basePath)

寫入hudi及同步數據至hive,需要注意的事情和如何處理?

  1. 聲明爲hudi表的path路徑, 非分區表 使用tablename/, 分區表根據分區路徑層次定義/個數

  2. 在創建表時需添加 TBLPROPERTIES 'spark.sql.sources.provider'='hudi' 聲明爲datasource爲hudi類型的表

hudi如何處理新增字段?

當使用Spark查詢Hudi數據集時,當數據的schema新增時,會獲取單個分區的parquet文件來推導出schema,若變更schema後未更新該分區數據,那麼新增的列是不會顯示,否則會顯示該新增的列;若未更新該分區的記錄時,那麼新增的列也不會顯示,可通過 mergeSchema來控制合併不同分區下parquet文件的schema,從而可達到顯示新增列的目的

hudi 寫入時指定mergeSchema參數 爲true

spark如何實現hudi表數據的寫入和讀取?

Spark支持用戶自定義的format來讀取或寫入文件,只需要實現對應的(RelationProvider、SchemaRelationProvider)等接口即可。而Hudi也自定義實現了 org.apache.hudi/ hudi來實現Spark對Hudi數據集的讀寫,Hudi中最重要的一個相關類爲 DefaultSource,其實現了 CreatableRelationProvider#createRelation接口,並實現了讀寫邏輯

kyuubi

如何讀取hudi表數據?

使用網易開源的kyuubi

kyuubi架構圖:

7atsdH.png

支持HiveServer2 Thrift API協議,可以通過beeline 連接

hive: beeline -u jdbc:hive2://ip:10000 -n userName -p 

kyuubi: beeline -u jdbc:hive2://ip:8333 -n userName -p 

hudi 元數據使用hive metastore

spark來識別加載hudi表

實現hudi表與hive表關聯查詢

kyuubi 支持SparkContext的動態緩存,讓用戶不需要每次查詢都動態創建SparkContext。作爲一個應用在yarn 上一直運行,終止beeline 連接後,應用仍在運行,下次登錄,使用SQL可以直接查詢

總結

本文主要針對hudi進行調研, 設計MySQL CDC 近實時同步至數倉中方案, 寫入主要利用hudi的upsert以及delete能力. 針對hudi 表的查詢,引入kyuubi 框架,除 了增強平臺 spark sql作爲即席查詢服務的能力外,同時支持查詢hudi表,並可以實現hudi表與hive表的聯合查詢, 同時對原有hive相關服務沒有太大影響.

參考

  1. https://blog.csdn.net/weixin_38166318/article/details/111825032
  2. https://blog.csdn.net/qq_37933018/article/details/120864648
  3. https://cxymm.net/article/qq_37933018/120864648
  4. https://www.jianshu.com/p/a271524adcc3
  5. https://jishuin.proginn.com/p/763bfbd65b70
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章