需要从 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
...
...

使配置生效:
source ~/.bashrc
# 确认 Java 版本
java -version

③ 安装 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
...
...

使配置生效:
source ~/.bashrc
# 确认 Java 版本
mvn -v

至此环境安装和配置完成。
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 那行:
... ... ... ...
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 作为参数就可以了。
运行完后容器会自动退出:


本章结束。