有關數倉增量和全量同步的一些思考

背景

相信很多公司都是基於Hive做的數倉,從而對外提供數據服務。這裏只討論離線數倉,做數倉必然離不開對大量數據的ETL處理工作。目前的ETL種類繁多,可選擇的工具也有很多,比如使用Sqoop, DataX做離線的T+1數據同步, Spark或者Flink做T+0的實時數據同步等。

目前有很多公司業務是T+1的,每天需要同步昨天的業務庫(MySQL、mongodb等)的數據到Hive數據倉庫中,這裏就涉及到大量數據同步的性能開銷問題。我司由於歷史原因,大量的MySQL表是全量同步的,而且由於某些原因居然還不帶時間字段比如:created_at,updated_at等,不過好在後面和DBA進行溝通補全了。我們直到sqoop是支持全量和增量進行數據同步的 參考Sqoop抽數的模式

但是數倉更多的是基於分區來做的,雖然sqoop可以只同步修改的,但是我們需要按天或者小時爲緯度獲得天級和小時級全量數據,所以纔有了本文。

注意事項

  1. 關於MySQL建表:
    必須有主鍵,必須有時間字段包含創建和修改,必須最小化使用字段類型,必須創建經常使用的字段索引,必須主從分離。
  2. 以下天級和小時級增量全量主要針對沒有歷史數據修改的情況。如果有歷史修改不好意思,需要重新刷下全量數據,或者乾脆就採用監聽MySQL binglog日誌做實時同步。

天級數據增量同步

思路: 每天將前天的全量數據和昨天的增量數據進行聚合(Union All)
這裏需要依賴一個天級增量任務:ods_xxx_record_di,ods_xxx_record_df任務會將ods_xxx_record_di作爲他的前置依賴,當ods_xxx_record_di任務運行完成後就開始使用hive或者sparksql計算ods_xxx_record_df 昨天的數據,時間從原先90+分鐘降到10+分鐘左右,效率提升非常明顯。

示例代碼

insert overwrite table ods.ods_xxx_df  partition (pt = '2019-09-25')
select 
id,student_id,bu,type,from_seller_id,to_seller_id,move_time,mark
from ods.ods_xxx_df where pt = '2019-09-24' 
union all
select
id,student_id,bu,type,from_seller_id,to_seller_id,move_time,mark
from ods.ods_xxx_di where pt = '2019-09-25';

小時級全量同步

思路:這個和上面天級的同理,只不過他獲取的是當天的數據,所以要注意調度系統的數據偏移。具體做法是拿昨天的天級全量數據和今天的天小時級做聚合(Union All),所謂天小時級並非真的小時級,大家的理解可能是pt=‘2019-09-26’,hour=12 我們這裏爲了簡化直接用了 pt=‘2019092612’ 代表了當天從0點到當前執行時間的上一個小時的天小時級數據。

示例代碼

insert overwrite table ods.ods_xx_xx_hf  partition (pt = '2019092614')
select 
id,bu,type,move_time,mark
from ods.ods_xx_xx_df where pt = '2019-09-25' 
union all
select
id,bu,type,move_time,mark
from ods.ods_xx_xx_hi where pt = '2019092614';

我們知道使用Sqoop可以設置按照某個字段進行split,可以依據需要設置併發數,但是也並不是設置的值越大越好,如果存在帶寬限制,或者MySQL未主從分離,那業務庫在拉數據的時候壓力相當大,尤其是我們有不少2億+以上的大表,每天需要全量拉取,那壓力可想而知。

其實做的所有努力都是爲了更好的支持業務,如果一開始就規劃好,我相信可以少走不少彎路,不多說了,一切都是爲了活下來!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章