datax - 艱難debug路

datax - 艱難debug路

第一次使用datax進行數據同步,bug慢慢啊,因此在此處把本身遇到的問題梳理作個總結,同時,對於datax進行一個簡單的介紹node

1. datax介紹

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

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

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

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

2. 從MySQL到HDFS

2.1 準備工做

從Mysql到hdfs中,須要作如下工做:數據庫

  • 準備MySQL端的數據,建表json

  • 準備hive端數據庫和表,在同步以前沒有相應的分區,所以還須要在hdfs的hive數據庫路徑下創建相應的分區 / 也能夠將此步驟 和 後面的同步任務寫在腳本中,定時運行便可。bash

  • 準備同步任務的json腳本併發

  • 同步以後,進行hive端的數據加載。app

如下是同步任務的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小時。
解決辦法有兩個:
一、轉換爲string類型;
二、繼續用timestamp類型,可是須要行存儲(即text存儲)。

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

相關文章
相關標籤/搜索