DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、OTS、ODPS 等各种异构数据源之间高效的数据同步功能。
例子:
全量从MYSQL 同步到MYSQL
{
"job": {
"content":[
{
"reader":{
"name":"mysqlreader",
"parameter":{
"connection":[
{
"querySql":["SELECT * FROM TABEL"],
"jdbcUrl":["jdbc:mysql://127.0.0.1:3306/dsjglpt"],
}
],
"username":"root",
"password":"123456",
"mandatoryEncoding":"UTF-8"
}
},
"writer":{
"name":"mysqlwriter",
"parameter":{
"column": ["*"],
"connection":[
{
"jdbcUrl":"jdbc:mysql://127.0.0.1:3306/dsjglpt_tmp",
"table":["TABEL"],
}
],
"username":"root",
"password":"123456",
"mandatoryEncoding":"UTF-8",
"preSql": ["truncate table TABEL"],
"writeMode": "insert"
}
}
}
],
"setting":{
"errorLimit":{
"record":0
},
"speed":{
"channel":"1"
}
}
}
}
从 MYSQL 同步到 PostgreSQL , 部分配置如下:
"name": "postgresqlwriter"
"jdbcUrl": "jdbc:postgresql://[target_server]:5432/[target_db]",
编写 ty_commit_datax_sjyc.sh (并发任务数)
if [ $# -lt 1 ] ; then
echo "请输入正确的参数:并发任务数 "
exit 1;
fi
processNum=$1
##基础路径
base=/home/admin
##新版本的datax
dataxHome=/home/admin/datax/datax3
##配置文件目录
confBase=`ls ${base}/sjyc/*.json`
##全量json目录
qlJsonPath="${base}/sjyc"
##如果统计表记录数文件不存在,需先执行统计表记录数脚本
#if [ ! -f ${shellPath}/log/count/${syscode}_CountTable.conf ] ;then
# echo "表记录数文件${syscode}_CountTable.conf不存在,请先执行统计记录数脚本!"
# exit 1;
#fi
startTime=`date '+%Y%m%d%H%M%S'`
##输出日志路径
outpath="${base}/log/commit/sjyc/${startTime}"
if [ -d ${outpath} ] ;then
rm -rf ${outpath}
fi
mkdir -p ${outpath}
touch ${outpath}/commitJson.log
touch ${outpath}/succJson.log
touch ${outpath}/failJson.log
mkdir -p ${outpath}/succLog
mkdir -p ${outpath}/failLog
jsonNum=`ls ${qlJsonPath}/*.json | wc -l`
if [ ${processNum} -gt ${jsonNum} ] ;then
echo "并发任务数必须小于等于json文件数:${jsonNum}"
exit 1;
fi
##以当前进程号命名
fifoName="/tmp/$$.fifo"
mkfifo ${fifoName}
##定义文件描述符(fd是一个整数,可理解为索引或指针),以读写的方式绑定到文件描述符3中
exec 3<>"${fifoName}"
##此时可以删除管道文件,保留fd即可
rm -rf ${fifoName}
##定义进程数量,向管道文件中写入进程数量个空行
for ((i=1;i<=${processNum};i++)) do
echo >&3
done
##组装dataX 动态参数
##根据配置文件ty_createJson.conf中的表匹配json目录下的json文件,如果一个表匹配到多个json文件(分区表的情况),则依次提交
for file in `ls ${qlJsonPath}/*.json` ;do
##读入一个空行
read -u3
{
jsonName="${file##*/}"
fileName="${jsonName%%.*}"
echo ${jsonName}
echo "${file}" >> ${outpath}/commitJson.log
python ${dataxHome}/bin/datax.py ${file} 2>&1 >> ${outpath}/${fileName}.log
result=$?
if [ ${result} -eq 0 ] ;then
echo "${fileName}" >> ${outpath}/succJson.log
mv -f ${outpath}/${fileName}.log ${outpath}/succLog
else
echo "${fileName}" >> ${outpath}/failJson.log
mv -f ${outpath}/${fileName}.log ${outpath}/failLog
##记录失败的表配置
#echo "${line}" >> ${confBase}/ty_createJson_bsj.conf
fi
#sleep 1
##最后向管道文件中写入一个空行
echo >&3
}&
done
done
wait
echo "开始时间:${startTime}" >> ${outpath}/commitJson.log
echo "开始时间:${startTime}"
endTime=`date '+%Y%m%d%H%M%S'`
echo "结束时间:${endTime}" >> ${outpath}/commitJson.log
echo "结束时间:${endTime}"
#关闭文件描述符的读
exec 3<&-
#关闭文件描述符的写
exec 3>&-
exit 0
编写CRONTAB 脚本(每天6点半执行 每次执行10个JSON文件)
crontab-e
30 6 * * * /home/admin/ty_commit_datax_sjyc.sh 10
------------------------------------------------------------------
要实现增量更新, 首先要 PostgresqlReader 从目标数据库读取最大日期, 并用 TextFileWriter 写入到一个 csv 文件, 这一步我的配置如下所示:
{
"job": {
"content": [
{
"reader": {
"name": "postgresqlreader",
"parameter": {
"connection": [
{
"jdbcUrl": [
"jdbc:postgresql://[target_server]:5432/[target_db]"
],
"querySql": [
"SELECT max(data_time) FROM public.minute_data"
]
}
],
"password": "...",
"username": "..."
}
},
"writer": {
"name": "txtfilewriter",
"parameter": {
"dateFormat": "yyyy-MM-dd HH:mm:ss",
"fileName": "minute_data_max_time_result",
"fileFormat": "csv",
"path": "/scripts/",
"writeMode": "truncate"
}
}
}
],
"setting": { }
}
}
最后编写增量同步的 shell 文件, 内容如下:
#!/bin/bash
### every exit != 0 fails the script
set -e
# 获取目标数据库最大数据时间,并写入一个 csv 文件
docker run --interactive --tty --rm --network compose --volume $(pwd):/scripts \
beginor/datax:3.0 \
/scripts/minute_data_max_time.json
if [ $? -ne 0 ]; then
echo "minute_data_sync.sh error, can not get max_time from target db!"
exit 1
fi
# 找到 DataX 写入的文本文件,并将内容读取到一个变量中
RESULT_FILE=`ls minute_data_max_time_result_*`
MAX_TIME=`cat $RESULT_FILE`
# 如果最大时间不为 null 的话, 修改全部同步的配置,进行增量更新;
if [ "$MAX_TIME" != "null" ]; then
# 设置增量更新过滤条件
WHERE="DataTime > '$MAX_TIME'"
sed "s/1=1/$WHERE/g" minute_data.json > minute_data_tmp.json
# 将第 45 行的 truncate 语句删除;
sed '45d' minute_data_tmp.json > minute_data_inc.json
# 增量更新
docker run --interactive --tty --rm --network compose --volume $(pwd):/scripts \
beginor/datax:3.0 \
/scripts/minute_data_inc.json
# 删除临时文件
rm ./minute_data_tmp.json ./minute_data_inc.json
else
# 全部更新
docker run --interactive --tty --rm --network compose --volume $(pwd):/scripts \
beginor/datax:3.0 \
/scripts/minute_data.json
fi