DataX實戰應用

目錄

前言

系統架構

關鍵實現

系統目前使用現狀

DataX使用心得


前言

DataX是阿里開源數據同步工具,實現異構數據源的數據同步,Github地址:https://github.com/alibaba/DataX,企業存儲離線數據到數倉,但是沒辦法對接業務,本次實踐主要是運用DataX實現數據從數倉導入到MySQL,從而對接業務,另外,對數倉數據的流出進行管理。

一般從數倉數據導入到MySQL中,可以從hive查詢存儲到一個文件裏面,如果是數據量比較大的情況下先將文件按一定行數切分爲多個文件,然後遍歷文件往MySQL中導入,這種方式雖然簡單,缺點在於對於每一個導入需求,都需要寫一個job,並且每次都會產生臨時文件,mysql load會比較佔用資源,之所以選擇了DataX,因爲它能實現hdfs導入MySQL,速度快,能實現增量全量,可以分表,能減少很多技術的實現成本。

系統架構

本次應用主要需實現一個Client和Server,依託於Hadoop集羣,通過Schedule基礎平臺定時調度調用client實現數據的同步。Server是一個管理項目,後端使用Spring MVC工程,對接了元數據系統,直接從前端頁面可以配置從Hive表導入到具體的MySQL表,client是一個jar包,通過HTTP和MQ和Server通信。

運行流程

1.Schedule通過java -jar client.jar啓動client

2.client通過http接口調用到server,獲取到本次要同步的一個job,通過job的信息生成一個json串,分配一個線程,client中通過python datax.py xxx.json調用DataX完成數據同步

3.client完成json文件的輸出,輸出到指定的文件夾下,文件名採用時間戳命名。

4. client中通過執行shell命令完成對DataX的調用

發佈流程:

1.DataX部署,這裏只使用到了mysqlwriter和hdfsreader組件,所以通過clone DataX源碼,刪除掉了其餘不用的組件代碼,手動編譯進行部署,編譯後大約佔用200M空間,部署到hadoop集羣的各個slave機器,正常情況下DataX只需要一次部署。

2.server發佈,server通過jenkins發佈爲一個web工程,後端提供http接口,並監聽MQ。

3.client發佈,client通過jenkins發佈到hadoop集羣的slave機器。

關鍵實現

1.日誌監控,schedule調起client任務一次對應的日誌應該都要全部輸出到schedule中,並且應該要捕捉到DataX的運行日誌。關鍵代碼:

//commond是運行DataX的命令:python datax/bin/datax.py xxx.json 
Process process = RUNTIME.exec(command);
try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
	String line;
	while ((line = input.readLine()) != null) {
		System.out.println(line);
	}
} catch (IOException e) {
	LOG.error("讀取DataX中job運行日誌異常", e);
}

2.作業告警,採用了Schedule調度系統的告警,DataX導入失敗會觸發調度系統的告警,然後通過電話和郵件對負責人進行通知。

3.Hive分區表,hive中對單個表進行分區存儲,一般按照日期進行分區,在schedule調起client時可以傳入一個日期參數,然後根據日期生成一個日期分區,在hdfsreader中的分區中帶入即可:

 "path": "/user/hive/warehouse/order/20180831",
 "defaultFS": "hdfs://localhost:2181",

4.MySQL增量和全量,DataX很貼心,mysqlwriter可以選擇導入的模式。

"writer":{
    "name": "mysqlwriter",
    "parameter": {
        "writeMode": "insert",  // 寫入模式可以選擇insert/replace/update
        "username": "root",
        "password": "root",
        "column": [
            "id",
            "name"
        ],
        "session": [
            "set session sql_mode='ANSI'"
        ],
        "preSql": [
            "delete from test" // 預執行SQL,可以選擇一個delete語句
        ],
        "connection": [
            {
                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/datax?useUnicode=true&characterEncoding=gbk",
                "table": [
                    "test"
                ]
            }
        ]
    }
}

其中parameter中的writeMode可以選擇insert,update,replace。並且有preSql選項,也就是在導入之前可以執行一些SQL,對我們全量數據和增量數據提供了有效的方案。

全量數據導入:通過preSql傳入一條delete語句,然後writerMode選擇insert執行導入(甚至如果有比較高的權限,可以直接用truncate語句,但是一般dba纔有的這樣權限),在delete的時候需要注意,如果數據量太大的情況下,一條delete就足以讓dba找上門拉,所以添加索引就有必要拉,根據索引刪除就會快一些。

增量數據導入:選擇writeMode使用update,這裏dataX是通過on duplicate key update語句來實現數據的增量實現,也就是說表裏面有唯一鍵或者主鍵衝突時,覆蓋原來的數據,這就很容易理解了,比如訂單數據,訂單號肯定是一個唯一鍵,如果導入一個已存在的訂單,數據肯定會覆蓋原來的數據。

5.爲什麼要用MQ,這裏client在調用DataX執行完成之後,應該要通知到server,當前的任務執行完畢,server會更新當前任務的狀態,對於簡單檢查任務的狀態時,就不用去查看schedule中的日誌了。

系統目前使用現狀

1.穩定性強,系統上線2個月以來,有大約20個作業在運行,其中有5個小時運行的作業,從來沒有出現過問題。

2.速度快,目前同步數據量最大的一個表大概是1.4億的數據量,同步的時間在1100s左右,也就是18分鐘到19分鐘這樣一個時間,每秒最高寫入量達到14w+,平均每秒寫入量大約在13w左右的速度,速度保持一個平均的趨勢,下面是一個運行結果的截圖

DataX使用心得

1.DataX是一個高可用的數據同步工具,穩定性強,速度快,上手快(不知道二次開發會不會困難,有機會可以試試,但是目前的功能已經能滿足很大一部分需求)。

2.事務的支持不足,在github上看到的DataX支持的一個線程中的事務,在測試過程中沒有體會到這種小事務能帶來多大的收益,在有髒數據的情況下,如果當前線程的數據出現問題執行回滾,其實對於整體來說數據是不完整的,還是有一部分數據已經導入到MySQL 了,所以單個線程的事務其實對於數據量較大的數據來說收益不大,除非作業是通過一個線程來跑的。

但是,另一方面,如果在大量數據導入執行一個事務,對MySQL來說無疑是一個災難,所以最好的辦法是保證系統結構穩定。

這裏其實有一個辦法,如果是全量的數據,在job跑失敗之後重新跑,能證數據的準確性,但是跑失敗的那段時間數據是有缺失的;如果是增量數據導入,重新跑一下job也能保證數據沒有問題。但是在那段小時間內還是有問題的。

確實是沒有什麼好的辦法去支持完整的事務。

歡迎交流。

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