DataX 实践(一)构建 DataX 的 Docker 容器镜像并测试运行

需要从 PostgreSQL 同步数据到 MongoDB,看了一圈选择了 DataX 工具,阿里的开源项目还是蛮值得信赖的。
官方并未提供 Docker 镜像,但是考虑到我现在已经部署了 K3s 集群,所以决定折腾下,自己构建个镜像来用。


参考文章:Docker 运行 DataX 实现数据同步方案
我的 Dockerfile 文件:DataX-docker
我构建完的 Docker 镜像:rabbir/datax

1、安装和配置 DataX 运行环境

官方描述的运行环境:

  • Linux
  • JDK(1.8 以上,推荐 1.8)
  • Python(推荐 Python2.6.X)
  • Apache Maven 3.x (Compile DataX)

① 直接拉取 CentOS7 的镜像,解决 Linux 和 Python 需求(CentOS7 官方镜像自带 Python2.7.5):

# 拉取镜像
docker pull centos:centos7
# 运行镜像
docker run -it docker.io/centos:centos7 /bin/bash

之后的命令都是在容器内执行!

② 安装 JDK1.8:

# 安装位置
cd /usr/local/
# 下载压缩包
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie"  http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz
# 解压并重命名
tar -zxvf jdk-8u131-linux-x64.tar.gz
mv jdk1.8.0_131 jdk1.8
# 删除压缩包
rm -f jdk-8u131-linux-x64.tar.gz
# 配置环境变量
vi ~/.bashrc

新增以下两行:

...
...
# Java 相关
export JAVA_HOME=/usr/local/jdk1.8
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
...
...

Java 配置
使配置生效:

source ~/.bashrc
# 确认 Java 版本
java -version

Java 版本

③ 安装 Apache Maven:

# 安装位置
cd /usr/local/
# 下载压缩包
wget --no-check-certificate https://dlcdn.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
# 解压并重命名
tar -zxvf apache-maven-3.6.3-bin.tar.gz
mv apache-maven-3.6.3 maven
# 删除压缩包
rm -f apache-maven-3.6.3-bin.tar.gz
# 配置环境变量
vi ~/.bashrc
...
...
# Maven 相关
export MAVEN_HOME=/usr/local/maven
export PATH=$PATH:$MAVEN_HOME/bin
...
...

Maven 配置
使配置生效:

source ~/.bashrc
# 确认 Java 版本
mvn -v

Maven 版本
至此环境安装和配置完成。

2、下载并编译 DataX
官方文档:Quick Start

cd /usr/local/
yum -y install git
# 克隆源码
git clone https://github.com/alibaba/DataX.git
# 编译
cd DataX
mvn -U clean package assembly:assembly -Dmaven.test.skip=true

我碰到的问题:
① oscarwriter JAR 包的缺失:

[ERROR] Failed to execute goal on project oscarwriter: Could not resolve dependencies for project com.alibaba.datax:oscarwriter:jar:0.0.1-SNAPSHOT: Could not find artifact com.oscar:oscar:jar:7.0.8 at specified path /usr/local/DataX/oscarwriter/src/main/lib/oscarJDBC.jar -> [Help 1]

解决方法就是去 pom.xml 中注释掉,反正也用不到。编辑源码根目录的 pom.xml 文件:

vi pom.xml

注释掉 oscarwriter 那行:

...
...
<!-- <module>oscarwriter</module> -->
...
...

Docker 容器性能受限,整体编译大概需要 10 分钟左右(我是因为出了错重新编译跳过了编译成功的包,所以只用了 3 分钟)。
编译完成
编译完成后,DataX 的可运行的 .py 文件会在 /usr/local/DataX/target/datax/datax/bin/ 路径下,测试一下:

cd /usr/local/DataX/target/datax/datax/bin/
# 查看配置模板
python datax.py -r streamreader -w streamwriter

如下输出说明 DataX 安装完成:
安装完成

3、构建 Docker 容器镜像并运行
① 首先写个正常能跑的测试用配置文件:

# 放在不同路径下
vi /root/stream2stream.json
{
  "job": {
    "content": [
      {
        "reader": {
          "name": "streamreader",
          "parameter": {
            "sliceRecordCount": 10,
            "column": [
              {
                "type": "long",
                "value": "10"
              },
              {
                "type": "string",
                "value": "Hello DataX!"
              }
            ]
          }
        },
        "writer": {
          "name": "streamwriter",
          "parameter": {
            "encoding": "UTF-8",
            "print": true
          }
        }
      }
    ],
    "setting": {
      "speed": {
        "channel": 5
       }
    }
  }
}

跑一下:

python datax.py /root/stream2stream.json 

datax.py 自带对路径的判断,因此在任何目录下去执行都没有问题,如下命令会收获一样正常运行的结果:

cd /root
python /usr/local/DataX/target/datax/datax/bin/datax.py stream2stream.json

测试配置文件

② 将上述所有命令写入 Dockerfile(部分命令如环境变量的配置会有所不同):

# 基础镜像系统版本为 CentOS:7
FROM centos:7

# 维护者信息
LABEL maintainer="Rabbir [email protected]"

# Docker 内用户切换到 root
USER root

# 设置时区为东八区
ENV TZ Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime > /etc/timezone

# 安装 Git 和 Wget
RUN yum -y install wget
RUN yum -y install git

# 切换到 /usr/local/ 目录下
WORKDIR /usr/local/
# 下载解压 JDK
RUN wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie"  http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz
RUN tar -zxvf jdk-8u131-linux-x64.tar.gz
RUN mv jdk1.8.0_131  jdk1.8
RUN rm -f jdk-8u131-linux-x64.tar.gz
# 下载解压 Maven
RUN wget https://dlcdn.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz --no-check-certificate
RUN tar -zxvf apache-maven-3.6.3-bin.tar.gz
RUN mv apache-maven-3.6.3 maven
RUN rm -f apache-maven-3.6.3-bin.tar.gz

# 添加容器内的永久环境变量
RUN sed -i "2 a export JAVA_HOME=/usr/local/jdk1.8" /etc/profile
RUN sed -i "3 a export PATH=\$PATH:\$JAVA_HOME/bin" /etc/profile
RUN sed -i "4 a export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar" /etc/profile
RUN sed -i "5 a export MAVEN_HOME=/usr/local/maven" /etc/profile
RUN sed -i "6 a export PATH=\$PATH:\$MAVEN_HOME/bin" /etc/profile
RUN source /etc/profile
RUN sed -i '1 a source /etc/profile' ~/.bashrc
RUN source ~/.bashrc

# 添加构建用的临时环境变量
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $PATH:$JAVA_HOME/bin
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV MAVEN_HOME /usr/local/maven
ENV PATH $PATH:$MAVEN_HOME/bin

# 克隆并编译 DataX 的源码
WORKDIR /usr/local/
RUN git clone https://github.com/alibaba/DataX.git
WORKDIR /usr/local/DataX/
RUN sed -i "s#<module>oscarwriter</module>#<!-- <module>oscarwriter</module> -->#" pom.xml
RUN mvn -U clean package assembly:assembly -Dmaven.test.skip=true

# 创建配置文件存放用文件夹
RUN mkdir /data
WORKDIR /data

# 启动命令
ENTRYPOINT ["/usr/bin/python", "/usr/local/DataX/target/datax/datax/bin/datax.py"]
CMD [""]

构建(镜像名和版本自行替换):

docker build -t rabbir/datax:latest .

因为需要读取配置文件,而 Docker 运行时是不支持将本地文件作为参数传入的,因此需要配置一下宿主机和容器内 /data 文件夹的映射,参考以下命令:

docker run --name datax_test_container -v /rab/docker/datax/data:/data rabbir/datax:latest test/stream2stream.json

解释:配置文件在宿主机内的完整路径为:/rab/docker/datax/data/test/stream2stream.json,那么通过映射它在容器内的路径则为:/data/test/stream2stream.json,此时就只需要传入 test/stream2stream.json 作为参数就可以了。

运行完后容器会自动退出:
运行完成
自动退出

本章结束。