datax 导入数据中文乱码_DataX在有赞大数据平台的实践
文| 小木 on 大數(shù)據(jù)
一、需求
有贊大數(shù)據(jù)技術應用的早期,我們使用 Sqoop 作為數(shù)據(jù)同步工具,滿足了 MySQL 與 Hive 之間數(shù)據(jù)同步的日常開發(fā)需求。
隨著公司業(yè)務發(fā)展,數(shù)據(jù)同步的場景越來越多,主要是 MySQL、Hive 與文本文件之間的數(shù)據(jù)同步,Sqoop 已經不能完全滿足我們的需求。在2017年初,我們已經無法忍受 Sqoop 給我們帶來的折磨,準備改造我們的數(shù)據(jù)同步工具。當時有這么些很最痛的需求:
多次因 MySQL 變更引起的數(shù)據(jù)同步異常。MySQL 需要支持讀寫分離與分表分庫模式,而且要兼容可能的數(shù)據(jù)庫遷移、節(jié)點宕機以及主從切換
有不少異常是因為表結構變更導致。MySQL 或 Hive 的表結構都可能發(fā)生變更,需要兼容多數(shù)的表結構不一致情況
MySQL 讀寫操作不要影響線上業(yè)務,不要觸發(fā) MySQL 的運維告警,不想天天被 DBA 噴
希望支持更多的數(shù)據(jù)源,如 HBase、ES、文本文件
作為數(shù)據(jù)平臺管理員,還希望收集到更多運行細節(jié),方便日常維護:
統(tǒng)計信息采集,例如運行時間、數(shù)據(jù)量、消耗資源
臟數(shù)據(jù)校驗和上報
希望運行日志能接入公司的日志平臺,方便監(jiān)控
二、選型
基于上述的數(shù)據(jù)同步需求,我們計劃基于開源做改造,考察的對象主要是 DataX 和 Sqoop,它們之間的功能對比如下
| 運行模式 | 單進程多線程 | MR |
| MySQL讀寫 | 單機壓力大;讀寫粒度容易控制 | mr模式重,寫出錯處理麻煩 |
| Hive讀寫 | 單機壓力大 | 很好 |
| 文件格式 | orc支持 | orc不支持,可添加 |
| 分布式 | 不支持,可以通過調度系統(tǒng)規(guī)避 | 支持 |
| 流控 | 有流控功能 | 需要定制 |
| 統(tǒng)計信息 | 已有一些統(tǒng)計,上報需定制 | 沒有,分布式的數(shù)據(jù)收集不方便 |
| 數(shù)據(jù)校驗 | 在core部分有校驗功能 | 沒有,分布式的數(shù)據(jù)收集不方便 |
| 監(jiān)控 | 需要定制 | 需要定制 |
| 社區(qū) | 開源不久,社區(qū)不活躍 | 一直活躍,核心部分變動很少 |
DataX 主要的缺點在于單機運行,而這個可以通過調度系統(tǒng)規(guī)避,其他方面的功能均優(yōu)于 Sqoop,最終我們選擇了基于 DataX 開發(fā)。
三、前期設計
3.1 運行形態(tài)
使用 DataX 最重要的是解決分布式部署和運行問題,DataX 本身是單進程的客戶端運行模式,需要考慮如何觸發(fā)運行 DataX。
我們決定復用已有的離線任務調度系統(tǒng),任務觸發(fā)由調度系統(tǒng)負責,DataX 只負責數(shù)據(jù)同步。這樣就復用的系統(tǒng)能力,避免重復開發(fā)。關于調度系統(tǒng),可參考文章《大數(shù)據(jù)開發(fā)平臺(Data Platform)在有贊的最佳實踐》。
DataX在有贊大數(shù)據(jù)平臺的上下文
在每個數(shù)據(jù)平臺的 worker 服務器,都會部署一個 DataX 客戶端,運行時可同時啟動多個進程,這些都由調度系統(tǒng)控制。
3.2 執(zhí)行器設計
為了與已有的數(shù)據(jù)平臺交互,需要做一些定制修改:
符合平臺規(guī)則的狀態(tài)上報,如啟動/運行中/結束,運行時需上報進度,結束需上報成功失敗
符合平臺規(guī)則的運行日志實時上報,用于展示
統(tǒng)計、校驗、流控等子模塊的參數(shù)可從平臺傳入,并需要對結果做持久化
需要對異常輸入做好兼容,例如 MySQL 主從切換、表結構變更
3.3 開發(fā)策略
大致的運行流程是:
前置配置文件轉換、表結構校驗->(輸入->DataX核心+業(yè)務無關的校驗->輸出)->后置統(tǒng)計/持久化
盡量保證 DataX 專注于數(shù)據(jù)同步,盡量不隱含業(yè)務邏輯,把有贊特有的業(yè)務邏輯放到 DataX 之外,數(shù)據(jù)同步過程無法滿足的需求,才去修改源碼。
表結構、表命名規(guī)則、地址轉換這些運行時前置校驗邏輯,以及運行結果的持久化,放在元數(shù)據(jù)系統(tǒng)(參考《有贊數(shù)據(jù)倉庫元數(shù)據(jù)系統(tǒng)實踐》),而運行狀態(tài)的監(jiān)控放在調度系統(tǒng)。
四、源碼改造之路
4.1 支持 Hive 讀寫
DataX 并沒有自帶 Hive 的 reader 和 writer,而只有 HDFS 的 reader 和 writer。我們選擇在 DataX 之外封裝,把 Hive 讀寫操作的配置文件,轉換為 HDFS 讀寫的配置文件,另外輔助上 Hive DDL 操作。具體的,我們做了如下改造:
4.1.1 Hive 讀操作
根據(jù)表名,拼接出 HDFS 路徑。有贊的數(shù)據(jù)倉庫規(guī)范里有一條,禁止使用外部表,這使得 HDFS 路徑拼接變得容易。若是外部表,就需要從元數(shù)據(jù)系統(tǒng)獲取相應的路徑
Hive 的表結構獲取,需要依賴元數(shù)據(jù)系統(tǒng)。還需對 Hive 表結構做校驗,后面會詳細說明
4.1.2 Hive 寫操作
寫 Hive 的配置里不會指定 Hive 的文件格式、分隔符,需要讀取元數(shù)據(jù),獲取這些信息填入 HDFS 的寫配置文件
支持新建不存在的 Hive 表或分區(qū),能構建出符合數(shù)據(jù)倉庫規(guī)范的建表語句
4.2 MySQL -> Hive 兼容性
按 DataX 的設計理念,reader 和 writer 相互不用關心,但實際使用經常需要關聯(lián)考慮才能避免運行出錯。MySQL 加減字段,或者字段類型變更,都會導致 MySQL 和 Hive 的表結構不一致,需要避免這種不一致的運行出錯。
4.2.1 MySQL -> Hive 非分區(qū)表
非分區(qū)表都是全量導入,以 mysqlreader 配置為準。如果 MySQL 配置字段與 Hive 實際結構不一致,則把 Hive 表 drop 掉后重建。表重建可能帶來下游 Hive SQL 出錯的風險,這個靠 SQL 的定時檢查規(guī)避。
Hive 表重建時,需要做 MySQL 字段轉換為 Hive 類型,比如 MySQL 的 varchar 轉為 Hive 的 string。這里有坑,Hive 沒有無符號類型,注意 MySQL 的 int unsigned 的取值范圍,需要向上轉型,轉為 Hive 的 bigint;同理,MySQL 的 bigint unsigned 也需要向上轉型,我們根據(jù)實際業(yè)務情況大膽轉為 bigint。而 Hive 的 string 是萬能類型,如果不知道怎么轉,用 string 是比較保險的。
4.2.1 MySQL -> Hive 分區(qū)表
Hive 分區(qū)表不能隨意變更表結構,變更可能會導致舊分區(qū)數(shù)據(jù)讀取異常。所以寫Hive 分區(qū)表時,以 Hive 表結構為準,表結構不一致則直接報錯。我們采取了如下的策略
| a,b | a,b | 正常 |
| a,b,c | a,b | 忽略MySQL的多余字段,以Hive為準 |
| b,a | a,b | 順序不對,調整 |
| a | a,b | MySQL少一個,報錯 |
| a,c | a,b | 不匹配, 報錯 |
| 未指定字段 | a,b | 以Hive為準 |
這么做偏保守,對于無害的 Hive 分區(qū)表變更,其實可以大膽去做,比如 int 類型改 bigint、orc 表加字段。
4.3 適配 MySQL 集群
有贊并沒有獨立運行的 MySQL 實例,都是由 RDS 中間件管理著 MySQL 集群,有讀寫分離和分表分庫兩種模式。讀寫 MySQL 有兩種選擇,通過 RDS 中間件讀寫,以及直接讀寫 MySQL 實例。
| 連實例 | 性能好;不影響線上業(yè)務 | 當備庫維護或切換地址時,需要修改配置;開發(fā)者不知道備庫地址 |
| 連 RDS | 與普通應用一致;屏蔽了后端維護 | 對 RDS 造成額外壓力,有影響線上業(yè)務的風險;需要完全符合公司 SQL 規(guī)范 |
對于寫 MySQL,寫入的數(shù)據(jù)量一般不大,DataX 選擇連 RDS,這樣就不用額外考慮主從復制。
對于讀 MySQL,考慮到有大量的全表同步任務,特別是凌晨離線任務高峰流量特別大,避免大流量對 RDS 中間件的沖擊,DataX 選擇直連到 MySQL 實例去讀取數(shù)據(jù)。為了規(guī)避 MySQL 維護帶來的地址變更風險,我們又做了幾件事情:
元數(shù)據(jù)維護了標準的 RDS 中間件地址
主庫、從庫、RDS 中間件三者地址可以關聯(lián)和任意轉換
每次 DataX 任務啟動時,獲取最新的主庫和從庫地址
定期的 MySQL 連通性校驗
與 DBA 建立協(xié)作關系,變更提前通知
讀取 MySQL 時,對于讀寫分離,每次獲取其中一個從庫地址并連接;對于分表分庫,我們有1024分片,就要轉換出1024個從庫地址,拼接出 DataX 的配置文件。
4.4 MySQL 運維規(guī)范的兼容
4.4.1 避免慢 SQL
前提是有贊的 MySQL 建表規(guī)范,規(guī)定了建表必須有 int 自增主鍵。另一條運維規(guī)范,SQL 運行超過2s會被強行 kill 掉。
以讀取 MySQL 全表為例,我們把一條全表去取的 SQL,拆分為很多條小 SQL,而每條小 SQL 只走主鍵 id 的聚簇索引,代碼如下 select ... from table_name where id>? by id asc limit ?
4.4.2 避免過快讀寫影響其他業(yè)務
執(zhí)行完一條 SQL 后會強制 sleep 一下,讓系統(tǒng)不能太忙。無論是 insert 的 batchSize,還是 select 每次分頁大小,我們都是動態(tài)生成的,根據(jù)上一條運行的時間,運行太快就多 sleep,運行太慢就少 sleep,同時調整下一個批次的數(shù)量。
這里還有改進的空間,可以根據(jù)系統(tǒng)級的監(jiān)控指標動態(tài)調整速率,比如磁盤使用率、CPU 使用率、binlog 延遲等。實際運行中,刪數(shù)據(jù)很容易引起 binlog 延遲,僅從 delete 語句運行時間無法判斷是否刪的太快,具體原因尚未去深究。
4.5 更多的插件
除了最常用的 MySQL、Hive,以及邏輯比較簡單的文本,我們還對 HBase 的讀寫根據(jù)業(yè)務情況做了簡單改造。
我們還全新開發(fā)了 eswriter,以及有贊 kvds 的 kvwriter,這些都是由相關存儲的開發(fā)者負責開發(fā)和維護插件。
4.6 與大數(shù)據(jù)體系交互
4.6.1 上報運行統(tǒng)計數(shù)據(jù)
DataX 自帶了運行結果的統(tǒng)計數(shù)據(jù),我們希望把這些統(tǒng)計數(shù)據(jù)上報到元數(shù)據(jù)系統(tǒng),作為 ETL 的過程元數(shù)據(jù)存儲下來。
基于我們的開發(fā)策略,不要把有贊元數(shù)據(jù)系統(tǒng)的 api 嵌入 DataX 源碼,而是在 DataX 之外獲取 stdout,截取出打印的統(tǒng)計信息再上報。
4.6.2 與數(shù)據(jù)平臺的交互
數(shù)據(jù)平臺提供了 DataX 任務的編輯頁面,保存后會留下 DataX 運行配置文件以及調度周期在平臺上。調度系統(tǒng)會根據(jù)調度周期和配置文件,定時啟動 DataX 任務,每個 DataX 任務以獨立進程的方式運行,進程退出后任務結束。運行中,會把 DataX 的日志實時傳輸并展示到頁面上。
4.7 考慮更多異常
DataX 代碼中多數(shù)場景暴力的使用 catchException,缺乏對各異常場景的兼容或重試,一個大任務執(zhí)行過程中出現(xiàn)網絡、IO等異常容易引起任務失敗。最常見的異常就是 SQLException,需要對異常做分類處理,比如 SQL 異常考慮重試,批量處理異常改走單條依次處理,網絡異常考慮數(shù)據(jù)庫連接重建。
HDFS 對異常容忍度較高,DataX 較少捕獲異常。
4.8 測試場景改造
4.8.1 持續(xù)集成
為了發(fā)現(xiàn)低級問題,例如表遷移了但任務還在、普通表改成了分區(qū)表,我們每天晚上20點以后,會把當天運行的所有重要 DataX 任務“重放”一遍。
這不是原樣重放,而是在配置文件里加入了一個測試的標識,DataX 啟動后,reader 部分只會讀取一行數(shù)據(jù),而 writer 會把目標地址指向一個測試的空間。這個測試能保證 DataX基本功能沒問題,以及整個運行環(huán)境沒有問題。
4.8.2 全鏈路壓測場景
有贊全鏈路壓測系統(tǒng)通過 Hive 來生成數(shù)據(jù),通過 DataX 把生成好的數(shù)據(jù)導入影子庫。影子庫是一種建在生產 MySQL 里的 database,對普通應用不可見,加上 SQL 的特殊 hint 才可以訪問。
生產環(huán)境的全鏈路壓測是個高危操作,一旦配置文件有誤可能會破壞真實的生產數(shù)據(jù)。DataX 的 MySQL 讀寫參數(shù)里,加上了全鏈路壓測的標記時,只能讀寫特定的 MySQL 和 Hive 庫,并配置數(shù)據(jù)平臺做好醒目的提醒。
五、線上運行情況
DataX 是在2017年二季度正式上線,到2017年Q3完成了上述的大部分特性開發(fā),后續(xù)僅做了少量修補。到2019年Q1,已經穩(wěn)定運行了超過20個月時間,目前每天運行超過6000個 DataX 任務,傳輸了超過100億行數(shù)據(jù),是數(shù)據(jù)平臺里比較穩(wěn)定的一個組件。
期間出現(xiàn)過一些小問題,有一個印象深刻。原生的 hdfsreader 讀取超大 orc 文件有 bug,orc 的讀 api 會把大文件分片成多份,默認大于256MB會分片,而 datax 僅讀取了第一個分片,修改為讀取所有分片解決問題。因為256MB足夠大,這個問題很少出現(xiàn)很隱蔽。除此之外沒有發(fā)現(xiàn)大的 bug,平時遇到的問題,多數(shù)是運行環(huán)境或用戶理解的問題,或是可以克服的小問題。
六、下一步計劃
對于 DataX 其實并沒有再多的開發(fā)計劃。在需求列表里積累了十幾條改進需求,而這些需求即便1年不去改進,也不會影響線上運行,諸如臟數(shù)據(jù)可讀性改進、支持 HDFS HA。這些不重要不緊急的需求,暫時不會再投入去做。
DataX 主要解決批量同步問題,無法滿足多數(shù)增量同步和實時同步的需求。對于增量同步我們也有了成熟方案,會有另一篇文章介紹我們自研的增量同步產品。
擴展閱讀
大數(shù)據(jù)開發(fā)平臺(Data Platform)在有贊的最佳實踐
有贊數(shù)據(jù)倉庫元數(shù)據(jù)系統(tǒng)實踐
How we redesigned the NSQ - 其他特性及未來計劃
HBase 寫吞吐場景資源消耗量化分析及優(yōu)化
有贊大數(shù)據(jù)平臺安全建設實踐
Flink 在有贊實時計算的實踐
SparkSQL 在有贊的實踐
Druid 在有贊的實踐
實時計算在有贊的實踐-效率提升之路
-The End-
Vol.171
有贊技術團隊
為 300 萬商家,150 個行業(yè),200 億電商交易額
提供技術支持
微商城|零售|美業(yè)
微信公眾號:有贊coder? ? 微博:@有贊技術
技術博客:tech.youzan.com
The bigger the dream,?
the more important the team.
總結
以上是生活随笔為你收集整理的datax 导入数据中文乱码_DataX在有赞大数据平台的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vs调用python脚本_vs2013下
- 下一篇: 2018.9.10.Matlab实验二: