datax - 艱難debug路


datax - 艱難debug路

第一次使用datax進行數據同步,bug慢慢啊,所以在此處把自己遇到的問題梳理做個總結,同時,對於datax進行一個簡單的介紹

1. datax介紹

​ datax 數據同步離線工具,將不同數據源的同步抽象為從源頭數據源讀取數據的Reader插件,以及向目標端寫入數據的Writer插件,理論上DataX框架可以支持任意數據源類型的數據同步工作。同時DataX插件體系作為一套生態系統, 每接入一套新數據源該新加入的數據源即可實現和現有的數據源互通。

​ 安裝部署-安裝路徑,只需要進行相應的安裝解壓到相應的路徑即可。每次執行任務則是將使用/datax/bin/data.py文件來去執行相應的任務即可。

​ DataX執行同步任務得時候,將數據源讀取和寫入抽象成為Reader/Writer插件,納入到整個同步框架中。

  • Reader:Reader為數據采集模塊,負責采集數據源的數據,將數據發送給Framework。
  • Writer:Writer為數據寫入模塊,負責不斷向Framework取數據,並將數據寫入到目的端。
  • Framework:Framework用於連接reader和writer,作為兩者的數據傳輸通道,並處理緩沖,流控,並發,數據轉換等核心技術問題。

2. 從MySQL到HDFS

2.1 准備工作

從Mysql到hdfs中,需要做以下工作:

  • 准備MySQL端的數據,建表

  • 准備hive端數據庫和表,在同步之前沒有相應的分區,因此還需要在hdfs的hive數據庫路徑下建立相應的分區 / 也可以將此步驟 和 后面的同步任務寫在腳本中,定時運行即可。

  • 准備同步任務的json腳本

  • 同步之后,進行hive端的數據加載。

以下是同步任務的json腳本

{
  "job": {
    "setting": {
      "speed": {
        "channel": 1
      },
      "errorLimit": {
        "record": 0
      }
    },
    "content": [{
      "reader": {
        "name": "mysqlreader",
        "parameter": {
          "username": "數據庫用戶名",
          "password": "數據庫密碼",
          "column": [
            "字段1", "字段2"
          ],
          "where": "同步條件",
          "splitPk": "id",
          "connection": [{
            "table": [
              "MySQL端同步表名"
            ],
            "jdbcUrl": [
              "jdbc:mysql://數據庫IP:數據庫端口/對應的數據庫"
            ]
          }]
        }
      },
      "writer": {
        "name": "hdfswriter",
        "parameter": {
          "defaultFS": "hdfs://HDFS集群-IP:端口",
          "fileType": "text",
          "path": "hive端表對應的存儲路徑/dt=分區參數(分區按照實際情況可要可不要)",
          "fileName": "hive端表名$do_date.dat",
          "column": [{
            "name": "字段1",
            "type": "INT"
          },
            {
              "name": "字段2",
              "type": "STRING"
            }
          ],
          "writeMode": "append",
          "fieldDelimiter": "分割符"
        }
      }
    }]
  }
}

2.2 參數說明

setting 參數說明

​ 用來控制同步任務,包括並發通道channel 、字節流byte 、記錄流record 、同步速度speed

reader參數說明

        jdbcUrl    描述:數據庫地址。必填
        username   描述:數據源用戶名
        password   描述: 數據源指定用戶名的密碼
        table      描述: 所選取的需要同步的表
        column     描述:  所配置的表中需要同步的列名集合
        splitPk    描述:MysqlReader進行數據抽取時,如果指定splitPk,表示用戶希望使用splitPk代表的字段進行數據分片,DataX因此會啟動並發任務進行數據同步,這樣可以大大提供數據同步的效能。推薦splitPk用戶使用表主鍵,因為表主鍵通常情況下比較均勻,因此切分出來的分片也不容易出現數據熱點。splitPk僅支持整形數據切分,不支持浮點、字符串、日期等其他類型。如果用戶指定其他非支持類型MysqlReader將報錯
        where      描述:篩選條件,MysqlReader根據指定的column、table、where條件拼接SQL,並根據這個SQL進行數據抽取。在實際業務場景中,往往會選擇當天的數據進行同步,可以將where條件指定為gmt_create > $bizdate 。注意:不可以將where條件指定為limit 10,limit不是SQL的合法where子句.where條件可以有效地進行業務增量同步。如果不填寫where語句,包括不提供where的key或者value,DataX均視作同步全量數據。
        querySql   描述:在有些業務場景下,where這一配置項不足以描述所篩選的條件,用戶 可以通過該配置型來自定義篩選SQL。當用戶配置了這一項之后,DataX系統就會忽略table,column這些配置型,直接使用這個配置項的內容對數據進行篩選,例如需要進行多表join后同步數據,使用select a,b from table_a join table_b on table_a.id = table_b.id 。當用戶配置querySql時,MysqlReader直接忽略table、column、where條件的配置,querySql優先級大於table、column、where選項。

writer參數說明

    defaultFS   描述:Hadoop hdfs文件系統namenode節點地址。格式:hdfs://ip:端口;例如:hdfs://127.0.0.1:9000
    fileType    描述:文件的類型,目前只支持用戶配置為"text"或"orc"。 
    path        描述:存儲到Hadoop hdfs文件系統的路徑信息
    fileName    描述:HdfsWriter寫入時的文件名,實際執行時會在該文件名后添加隨機的后綴作為每個線程寫入實際文件名。 
    column      描述:寫入數據的字段,不支持對部分列寫入。為與hive中表關聯,需要指定表中所有字段名和字段類型,其中:name指定字段名,type指定字段類型。 
    writeMode   描述:hdfswriter寫入前數據清理處理模式: 
                § append,寫入前不做任何處理,DataX hdfswriter用filename寫入,並保證文件名不沖突。
                § nonConflict,如果目錄下有fileName前綴的文件,直接報錯。
    fieldDelimiter  描述:hdfswriter寫入時的字段分隔符,需要用戶保證與創建的Hive表的字段分隔符一致,否則無法在Hive表中查到數據 

2.3 執行任務

在做好所有的准備工作的時候,開始執行任務:

#!/bin/bash
source /etc/profile
source activate python27

do_date="`date +%Y-%m-%d`"

# 創建目錄
hdfs dfs -mkdir -p /user/hive/warehouse/xxx/xxx/dt=$do_date
# 數據遷移
python2 $DATAX_HOME/datax.py -p "-Ddo_date=$do_date" JSON腳本
# 加載數據
hive -e "alter table xxx庫.xxx表  add partition(dt='$do_date')"

3.出現的問題

問題1:數據庫連接問題

​ 第一: 地址錯誤 使用IP

​ 第二: 帳戶和密碼錯誤

​ 第三: 表名錯誤 / 字段問題

​ 對於這種問題,則是進行核查就好

問題2:HDFS 連接問題

​ 第一: HDFS地址問題 ,我犯了最最低級的問題,最開始使用了主機名,而沒有用IP

​ 第二:就是連接不上,可以反復重啟一下集群解決

問題3:內存不夠的問題,報了以下錯誤

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 160088 bytes for AllocateHeap
# An error report file with more information is saved as:
# /users/xxx/hs_err_pidxxxx.log

​ 出現這種問題,說明申請內存失敗,遇到這種問題,可能由以下兩種原因

  1. 系統物理內存或虛擬內存不足

  2. 程序在壓縮指針模式下運行, Java堆會阻塞本地堆的增長

    首先使用free-m 查詢,查看內存使用情況,如下圖所示已經是設置過后的圖,剩余內存也不是很多,針對內存過小的問題,通過修改配置文件即可。

image-20210108110229826

由於/proc/meminfo下的vm.overcommit_memory被設置成不允許overcommit造成的overcommit是指對虛擬內存的過量分配; 用戶進程申請的是虛擬地址,虛擬內存需要物理內存做支撐, 如果分配太多虛擬內存, 會對性能參數影響.

vm.overcommit_memory的用處: 控制過量分配的策略. 這個參數一共有3個可選值:

0: Heuristic overcommit handling. 就是由操作系統自己決定過量分配策略
1: Always overcommit. 一直允許過量分配
2: Don't overcommit. 不允許過量分配

通過sysctl vm.overcommit_memory 來查看overcommit_memory的參數設置

則通過以下幾種方式進行設置:

  1. /etc/sysctl.conf 文件中添加一行vm.overcommit_memory=1 即可,之后再使用sysctl -p 使配置文件永久生效當然這是我們在開發環境下的解決方式, 在生產環境還是要盡量去優化調整JVM的參數來保證每個程序都有足夠的內存來保證運行.
  2. echo 1 > /proc/sys/vm/overcommit_memory 此方式臨時生效,系統重啟后消失
  3. sudo sysctl vm.overcommit_memory=0, 即vm.overcommit_memory = 0, 允許系統自己決定過量分配策略

問題4:導入hive之后數據全為NULL

​ 出現這種問題,主要是分隔符的問題,在hive端建表的時候,設置分隔符最好和JSON腳本中的一致,在網上查了好多情況,有的說是要使用'\t' 分隔符,我測試的結果是我和JSON腳本中設置成一致成功了。

CREATE EXTERNAL
TABLE `ods_trade_shops` (
       `shopId` int,
       `userId` int
)
PARTITIONED by
(
    dt string
)
row format delimited fields terminated by ',';

問題5:在建表的時候需要注意以下,數據類型的問題。

MySQL數據類型 Datax數據類型 HIVE數據類型
int, tinyint, smallint, mediumint, int, bigint LONG int/tinyint/bigint/smallint
float, double, decimal DOUBLE float double
varchar, char, tinytext, text, mediumtext, longtext, year STRING string
date, datetime, timestamp, time DATE date/ timestamp/string
bit , bool BOOLEAN boolean

DATAX在轉換MySQL datatime字段類型為hive的timestamp時會出現問題:datax和hive不支持datetime類型,因此可能回出現同步之后時間字段多/少8小時。
解決辦法有兩個:
1、轉換為string類型;
2、繼續用timestamp類型,但是需要行存儲(即text存儲)。

遇見時間類型轉換問題時要小心,保守最好是string,簡單的比較大小不會影響后續計算。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM