数据同步之DataX

       目前业务中需要进行数据同步, 考虑使用datax数据同步方式替换掉现有的同步方式

 

业务场景:

    即将业务中每天生成的日志表中的数据部分字段同步到自己的库中,进行后台数据的查询

 

起因:

  之前“大神”写的逻辑中使用每三分钟更新一次的策略进行数据同步,在redis中进行计数和打标记的方式进行数据的增量同步,但是最近发现经常数据会发生丢失的问题,于是进行问题的修复

 

解决:

      了解到运营对于这些数据的查询实时性并没有这么高,今天查询昨天的数据这种场景比较多,于是打算使用datax凌晨同步昨天的数据到本地即可,节省资源,减少调用业务的数据库频次

      DataX: https://github.com/alibaba/DataX

      基于java的同步开源项目,基本使用起来较为容易,简单配置即可,完成之后 3万多的数据 只需要不到10秒中就完成了数据同步工作

      数据库-mysql相关的reader和writer相关配置参考:

  • https://github.com/alibaba/DataX/blob/master/mysqlwriter/doc/mysqlwriter.md
  • https://github.com/alibaba/DataX/blob/master/mysqlreader/doc/mysqlreader.md

     当然他还支持很多的数据库

 

安装)

  1)下载源码包

wget http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz

基于java, 保证已经安装了Java,推荐8版本,安装方式,可见本博客,

cd /usr/local/src/

wget https://repo.huaweicloud.com/java/jdk/8u201-b09/jdk-8u201-linux-x64.tar.gz
tar -zxvf jdk-8u201-linux-x64.tar.gz
mv jdk1.8.0_201 /usr/local/
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_201
export PATH=${JAVA_HOME}/bin:${PATH}

source /etc/profile
java -version 查看版本

 

   2)解压datax

tar -zxvf datax.tar.gz

执行一个demo
python datax/bin/datax.py datax/job/job.json


注意:这里使用的是python2 版本

 

 

2)示例

   1.MySQL同步到MySQL

{
    "job": {
        "setting": {
            "speed": {
                "byte":10485760
            },
            "errorLimit": {
                "record": 0,
                "percentage": 0.02
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "123456",
                        "connection": [
                            {
                                "querySql": [
                                    "select player_id,UNIX_TIMESTAMP(create_time) AS create_time from t_player_log__20210422"
                                ],
                                "jdbcUrl": [
                                    "jdbc:mysql://127.0.0.1:3306/demo"
                                ]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "root",
                        "password":"123456",
                        "column": [
                            "player_id",
                            "create_time"
                        ],
                        "session": [
                            "set names utf8mb4"
                        ],
                        "connection": [
                            {
                                "encoding": "UTF-8",
                                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/test",
                                "table": [
                                    "tt_player_log"
                                ]
                            }
                        ]
                    }
                }
            }
        ]
    }
}

  还支持传入参数的方式动态的配置(python bin/datax.py 支持的参数:-p),例如:

{
    "job": {
        "setting": {
            "speed": {
                "byte":10485760
            },
            "errorLimit": {
                "record": 0,
                "percentage": 0.02
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "${username}",
                        "password": "${password}",
                        "connection": [
                            {
                                "querySql": [
                                    "select player_id,UNIX_TIMESTAMP(create_time) AS create_time from t_player_log__${dateNum}"
                                ],
                                "jdbcUrl": [
                                    "jdbc:mysql://${ip}:${port}/${db}"
                                ]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "root",
                        "password":"123456",
                        "column": [
                            "player_id",
                            "create_time"
                        ],
                        "session": [
                            "set names utf8mb4"
                        ],
                        "connection": [
                            {
                                "encoding": "UTF-8",
                                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/test",
                                "table": [
                                    "${table}"
                                ]
                            }
                        ]
                    }
                }
            }
        ]
    }
}

  同步命令:

/bin/python /opt/datax/bin/datax.py /opt/datax/job/game_job.json -p"-Dusername=xxxx -Dpassword=xxx -Dip=xx.xx.xx.xx -Dport=3306 -Ddb=xx -Dtable=xx -DdateNum=20210423"

注意:如果密码中有特殊字符,需要使用单引号将其引起来

 

      相关的job任务会放到job目录下, 新建一个shell脚本放到script下, run_jobs.sh,将相关数据库连接配置到一个数据表中, 添加上定时任务即可

#!/bin/bash

#说明:
#    执行同步游戏库玩家日志表数据

day_num=`date -d "-1 day" +%Y%m%d`
#day_num=`date +%Y%m%d`


main(){
    mysql -hxx.xx.xx -Pxx -uxx -pxx -N -e "select game_name,app_id,ip,port,username,password,db_name,player_log_table from t
xx.tt_game_db where type=2 and status=1" | while read game_name app_id ip port username password db_name player_log_table
    do
        echo "当前游戏:$game_name[$app_id] 数据库信息:$username:$password@$ip:$port/$db_name 目标表:$player_log_table"
        #echo "-Dusername=$username -Dpassword=$password -Dip=$ip -Dport=$port -Ddb=$db_name -Dtable=$player_log_table -DdateNum=$day_num"
        /bin/python /opt/datax/bin/datax.py /opt/datax/job/game_job.json -p"-Dusername=$username -Dpassword=$password -Dip=$ip -Dport=$port -Ddb=
$db_name -Dtable=$player_log_table -DdateNum=$day_num" 

    done
}

main

 

  2)MongoDB同步到MySQL

{
  "job": {
      "setting": {
          "speed": {
              "channel": 2
          }
      },
      "content": [
          {
              "reader": {
                  "name": "mongodbreader",
                  "parameter": {
                      "address": ["127.0.0.1:27017"],
                      "userName": "dataxUser1",
                      "userPassword": "xxxxx",
                      "dbName": "log_1",
                      "collectionName": "20210101",
                      "column": [
                          {
                              "name": "uid",
                              "type": "int"
                          },
                          {
                              "name": "match_id",
                              "type": "string"
                          }
                      ],
                      "query": {  // 添加筛选条件
                          "func_name":"play",
                          "play_type": {
                              "$in": [2,3]
                          }
                      }
                  }
              },
              "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "gameUser",
                        "password": "xxxxx",
                        "column": [
                            "player_index",
                            "table_id"
                        ],
                        "session": [
                            "set names utf8mb4"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/game_log",
                                "table": [
                                    "game_record_log"
                                ]
                            }
                        ]
                    }
                }
          }
      ]
  }
}


注意点: 这里的MongoDB的用户名和密码 要开一个这个库的所属人的权限
db.createUser({user:"dataxUser1",pwd:"xxxx",roles:[{role:"dbOwner", db:"log_1"}]})

  后面为了通用, 需要将这里配置的MongoDB的信息和MySQL的信息都通过变量的方式传递进来

 

在script目录下添加shell执行脚本,例如:run_jobs_for_mongo2mysql.sh

#!/bin/bash
## 传入开始和结束时间将MongoDB(10十个库)中每个库指定日期范围内的数据同步到MySQL
begin_date=$1
end_date=$2
begin_time=$begin_date

mongo_user_prefix="dataxUser"
mongo_pwd=xxxx
mongo_db_name_prefix="log_"
mongo_table_name_prefix="game_"

mysql_user="mysqlUser"
mysql_pwd="xxx"
mysql_host="127.0.0.1"
mysql_port=3306
mysql_db_name="game_log"
mysql_table_name="game_record_log"

main(){
    for n in $(seq 1 10)
    do
        while [ "$begin_date" != "$end_date" ]
        do
            echo $begin_date
            mongo_user=$mongo_user_prefix$n
            mongo_db_name=$mongo_db_name_prefix$n
            mongo_table_name=$mongo_table_name_prefix$begin_date
            echo "-Dmongo_user=$mongo_user -Dmongo_pwd=$mongo_pwd -Dmongo_db_name=$mongo_db_name -Dmongo_table_name=$mongo_table_name -Dmysql_user=$mysql_user -Dmysql_pwd=$mysql_pwd -Dmysql_host=$mysql_host -Dmysql_port=$mysql_port -Dmysql_db_name=$mysql_db_name -Dmysql_table_name=$mysql_table_name"
        /bin/python /opt/data/datax/bin/datax.py /opt/data/datax/job/game_mongo2mysql_job.json -p"-Dmongo_user=$mongo_user -Dmongo_pwd=$mongo_pwd -Dmongo_db_name=$mongo_db_name -Dmongo_table_name=$mongo_table_name -Dmysql_user=$mysql_user -Dmysql_pwd='$mysql_pwd' -Dmysql_host=$mysql_host -Dmysql_port=$mysql_port -Dmysql_db_name=$mysql_db_name -Dmysql_table_name=$mysql_table_name"
            let begin_date=`date -d "-1 days ago ${begin_date}" +%Y%m%d`
        done
        begin_date=$begin_time
        echo $end_date
    done
}
main

 

 

 

 

常见问题:

   1.如果数据表中有特殊表情的时候, 可能会出现字符错误的报错信息, 这个时候需要进行设置

"session": [
      "set names utf8mb4"
],

 

 

 更多同步工具:

  • canal
  • CloudCanal(https://www.clougence.com/)

 

 

 

 

 

 

 

 

 

 

    

posted @ 2021-04-25 10:00  X-Wolf  阅读(1169)  评论(0编辑  收藏  举报