開始之前,先聊下企業(yè)數(shù)據(jù)的整體架構(gòu)吧。一般來(lái)說(shuō),業(yè)務(wù)系統(tǒng)的數(shù)據(jù)庫(kù)有較大的生產(chǎn)壓力,大多數(shù)的做法是在企業(yè)生產(chǎn)庫(kù)后會(huì)追加1到2個(gè)只讀庫(kù),負(fù)責(zé)實(shí)時(shí)同步主庫(kù)數(shù)據(jù)。業(yè)務(wù)系統(tǒng)寫入到只讀庫(kù),查詢數(shù)據(jù)從從庫(kù)。同時(shí)為了減輕成本壓力,從庫(kù)不提供binlog日志能力。

阿里巴巴的Dataworks作為一站式數(shù)據(jù)開發(fā)和數(shù)據(jù)治理的PASS平臺(tái),提供多樣的數(shù)據(jù)集成能力,甚至提供了數(shù)據(jù)集成的解決方案。為完成數(shù)倉(cāng)的ODS層的建設(shè),存在離線全量ETL、離線增量+離線全量的ETL、實(shí)時(shí)增量+離線全量ETL、實(shí)時(shí)增量ETL4種方式。這里我們從技術(shù)上進(jìn)行簡(jiǎn)單拆解,最終選擇一個(gè)較為合適的方案,為簡(jiǎn)化起見我們的源端是RDS,即mysql數(shù)據(jù)庫(kù)。
離線全量ETL:即使用Dataworks離線集成方式,配置源端mysql通過(guò)每日將全量數(shù)據(jù)抽取,并重寫到ODS表,這種方式也叫"直連"方式。通過(guò)直連源端(一般都會(huì)選擇從庫(kù)-.-,沒有從庫(kù)的話請(qǐng)運(yùn)維同事構(gòu)建吧,主庫(kù)拉掛了就可以祭天了)的方式,對(duì)于一般小表來(lái)說(shuō)(即整體看該表整體數(shù)據(jù)量比較固定,日增量較少,如組織架構(gòu)表)這種方式是可行的,且操作簡(jiǎn)單。遺憾的是:每日固定時(shí)間拉取的表數(shù)據(jù),嚴(yán)格來(lái)說(shuō)并不是某一個(gè)時(shí)間點(diǎn)的實(shí)際真是快照。如定時(shí)每天00:00:00同步數(shù)據(jù),但實(shí)際任務(wù)調(diào)度時(shí)會(huì)因調(diào)度資源爭(zhēng)奪等原因造成數(shù)據(jù)同步延遲(0點(diǎn)存在大量數(shù)據(jù)同步任務(wù)),實(shí)際落地到ODS的數(shù)據(jù)并非是00:00:00的快照。同時(shí)由于ODS數(shù)據(jù)同步的延遲,導(dǎo)致下游任務(wù)會(huì)停滯一段時(shí)間,數(shù)據(jù)的計(jì)算結(jié)果也會(huì)延遲一定時(shí)間,使用該方式之前需要從業(yè)務(wù)角度綜合分析。對(duì)于大表來(lái)說(shuō),該方式有點(diǎn)慢性自殺的感覺,數(shù)據(jù)同步慢,下游計(jì)算延遲,拉掛了只讀庫(kù)會(huì)不會(huì)祭天我不知道,我只知道工作還得做,數(shù)據(jù)計(jì)算還得補(bǔ)回來(lái),怎么解決呢?可以試試使用“離線增量+全量的ETL”的方式。

離線增量+離線全量的ETL:在特定情況下,如解析FTP文件日志、TableStore增量日志時(shí)該方案是最佳方案,也可以處理關(guān)系型數(shù)據(jù)庫(kù)RDS的場(chǎng)景,如對(duì)大表(如訂單表,每天增量100w+)可以考慮首次進(jìn)行數(shù)據(jù)的全量同步到MaxCompute里的全量表table_full,后續(xù)接入每日增量的數(shù)據(jù)同步到MaxCompute的增量表table_inc,在MaxCompute里完成數(shù)據(jù)合并并重寫到table_full的最新分區(qū)里。具體實(shí)踐:源端Mysql定義modify_time,數(shù)據(jù)每次修改會(huì)插入時(shí)都會(huì)更新該字段。定時(shí)抽取源端數(shù)據(jù)時(shí)增加過(guò)濾條件modify_time>start_time? and modify_time<end_time將ETL的數(shù)據(jù)寫入ODS增量表的分區(qū)里,再與ODS全量表最新分區(qū)數(shù)據(jù)進(jìn)行合并,并重新寫入到一個(gè)新的分區(qū)數(shù)據(jù)里。遺憾的是:該方式對(duì)于源庫(kù)來(lái)說(shuō)相當(dāng)于每次掃描一次全表(可以使用索引優(yōu)化)對(duì)源庫(kù)也存在一定的性能壓力。源端進(jìn)行了歷史數(shù)據(jù)的物理刪除的話,數(shù)據(jù)合并時(shí)無(wú)法感知,因此需要先與業(yè)務(wù)應(yīng)用系統(tǒng)確定數(shù)據(jù)是否存在物理刪除場(chǎng)景。怎么解決呢?可以試試使用"實(shí)時(shí)增量+離線全量ETL"的方式。

實(shí)時(shí)增量+離線全量ETL:工作原理與上述相同。唯一不同的是通過(guò)Mysql-binlog日志的方式實(shí)時(shí)寫入,通過(guò)解析binlog日志里的日志時(shí)間戳,將該時(shí)間戳轉(zhuǎn)為maxcompute增量表的分區(qū)字段,并根據(jù)日志的變更類型(新增、修改、刪除)、日志順序(record_id)與全量表進(jìn)行數(shù)據(jù)合并。該方案的解決了離線全量ETL中數(shù)據(jù)快照不精確的問題,并可以感知到源端數(shù)據(jù)庫(kù)物理刪除數(shù)據(jù)的場(chǎng)景,可以說(shuō)是相當(dāng)完美的方案了,這也是我實(shí)踐的方案,后續(xù)整體會(huì)圍繞該方案細(xì)說(shuō)。然而該方案對(duì)數(shù)據(jù)開發(fā)人員的技術(shù)要求較高。?如何采集binlog日志,如何進(jìn)行數(shù)據(jù)合并,阿里Dataworks已有了解決方案,下一章我將會(huì)細(xì)說(shuō)這塊"數(shù)據(jù)集成之實(shí)時(shí)增量+離線全量ETL詳解"。

實(shí)時(shí)增量ETL:嚴(yán)格上來(lái)說(shuō),該方案是上個(gè)方案的子集,單拎出來(lái)主要基于業(yè)務(wù)考慮。數(shù)據(jù)計(jì)算場(chǎng)景需要獲取源端完整數(shù)據(jù)的場(chǎng)景請(qǐng)使用上個(gè)方案。部分場(chǎng)景可能只需要關(guān)心當(dāng)前增量的數(shù)據(jù),不關(guān)心歷史數(shù)據(jù)的只需要進(jìn)行實(shí)時(shí)增量ETL。數(shù)據(jù)源也會(huì)多樣化如mysql-binlog、rockmq等等。數(shù)據(jù)的老化策略也會(huì)不同。這塊后期文章里會(huì)詳細(xì)說(shuō)明。

喜歡的朋友請(qǐng)幫忙點(diǎn)贊,謝謝大家!