记录datax使用过程中的一系列需要主要的地方以及优化和采用调度工具调度datax任务
1.使用crontab调度datax任务,仅做数据数据同步因为他的依赖关系不好定义,最好是处理一个一个单独的同步任务
2.首先我们需要建立对对应的同步任务,这我们假设建立了一个mysql2mysql的任务名为'***.json'
3.之后我们建立一个shell脚本去调度之前的datax同步任务
脚本内容:
#这一行在脚本中必须添加否无法执行
#!/bin/sh
#定义时间
time=$(date "+%Y-%m-%d %H:%M:%S")
#由于crontab不会刷新配置文件,我们手动刷新配置文件,防止任务同步失败
source /etc/profile
#也是刷新配置文件(最好有不然任务容易失败)
source ~/.bash_profile
#将日志对应到指定日期的文件中,例如2022年11月16日跑的任务,会产生一个对应日期的文件
echo `date "+%Y-%m-%d %H:%M:%S"` >> /opt/modules/datax/log/datax_log.log
#切换这datax所在的bin目录下
cd /opt/modules/datax/bin
#echo到控制台说明已经进入bin目录
echo '进入bin目录'
#通过python调度 对应目录下面的数据同步任务'***.json'
python datax.py /opt/modules/datax/job/job.json
#执行结束打印日志至控制台
echo 'hello!'
通过shell命令替换json或者某个文件中的某个值
替换文件为json:当我们想要动态替换掉文件中的某一个key的值的时候可以用,例如我们在datax动态同步数据的时候我们需要每天更改文件中的where字段, 按照时间的话我们就可以根据时间进行修改,这样是可行的
示例shell文件如下:
#!bin/bash
#其中的where是我需要替换的那个字段对应的key,{print NR}可以获取该key位于第几行
old_line=$(awk -F"\"" '/where/{print NR}' 自己的文件名)
#其中的where是我要替换的那个字段对应的key,{print $4}可以获取where对应的values
old_test=$(awk -F"\"" '/where/{print $4}' 自己的文件名)
new_test=自己想要替换成的值
#这里的意思是将文件中指定列的旧数据替换成新数据,适用于某个文本文件中可能存在多个的情况
sed -e "@$old_line s@$old_test@$new_test@" -i 自己的文件名
#这里的意思也是将文件中的旧数据替换成新数据,但是这个文本再文件中只有1个的时候就可以做到全局替换
sed -e "s@$old_test@$new_test@g" -i 自己的文件名
下面写一个具体的案例:我想替换test.json中where这个key所对应的值,后面的$4,实际应用的时候可以根据自己的json文件进行调试,$1,$2,$3……,看那个能拿到你想要的数据
#!bin/bash
#查找test.json文件中where对应的值
old_test=$(awk -F"\"" '/where/{print $4}' test.json)
#我治理想要将他替换成昨天的日期,时间格式为20221212
new_test=$(date -d yesterday +%Y%m%d)
#拼接where条件中的string,riqi=20221212类似于这种
new_test_final='riqi='$new_test
#替换掉test.json文件中where对应的字符
sed -e "s@$old_test@$new_test_final@g" -i test.json
通过编写crontab任务执行脚本
* * * * * (./etc/profile;/bin/sh) (脚本所在的目录位置)
添加./etc/profile;/bin/sh的目的,是为了使环境变量生效
其中* * * * *定义了脚本执行的频率,分别对应的是{minute},{hour},{day-of-month},{month},{day-of-week} {mintue}的区间为0-59 {hour}的区间为0-23 {day-of-month}的区间为0-31 {month}的区间为1-12 {day-of-week}的区间为0-7,这里的周日可以是0也可以是7
常用的crontab总结:
-- crontab -l:查看crontab的任务列表
-- systemctl stop crond.service:关闭crontab服务
-- crontab -e:编辑一个新的crontab任务
-- systemctl status crond.service:查看服务的状态
-- crontab -r:删除对应的crontab任务(慎用)
-- systemctl restart crond.service:重启服务
-- systemctl start crond.service:启动crontab服务
-- yum install crontabs:在未安装crontab的情况下安装
常用的* * * * * 总结:
--每一分钟执行一次:* * * * *
--每小时的第3分钟和第15分钟执行一次:3,15 * * * *
--每天8点到11点的第3分钟和第15分钟执行一次:3,15 8-11 * * *
--每隔2天的8点到11点的第3分钟和第15分钟执行一次:3,15 8-11 8/2 * *
--每周1上午的8点到11点的第三分钟和第5分钟执行一次:3,5 8-11 * * 1
--每晚的21点30分执行一次:30 21 * * *
--每月的1号10号21号的4点45分执行一次:45 4 1,10,21 * *
--每周六周日的1点10分执行一次:10 1 * * 6,0
--每天18点到23点之间每隔30分钟执行一次:0,30 18-23 * * *
--每周6晚上的23点执行一次:0 23 * * 6
--每小时执行一次:* */1 * * *
--每天晚上的23点到第二天早上7点,每间隔一个小时执行一次:* 23-7/1 * * *
--每个星期的第一天执行一次,即每个星期天晚上的24点开始执行:@weekly
--每个月的15号的11点执行一次:0 11 15 * *
--每个月的第一天执行一次,即每个月的第一天的0点开始执行:@monthly --在指定的月份执行一次,在1月4月6月每天晚上0点执行一次:0 0 * 1,4,6 *
--重启之后执行一次:@reboot
使用azkaban调度datax任务
可视化页面比较好维护,且可以很好的配置依赖关系(这里只对调度shell任务进行了描述,azkaban还可以调度很多其他的任务例如hive,hdfs,mr任务等)
1.首先我们需要建立对对应的同步任务,这我们假设建立了一个mysql2mysql的任务名为'***.json'
2.之后我们建立一个shell脚本去调度之前的哪个datax同步任务 ---脚本内容和上面一样---
3.之后我们在本地编写azkaban的job任务:1.vim ***.job 2.zip ***.job就可以完成打包
4.单纯的shell脚本调度
type=command
command=sh 脚本所在位置的绝对路径
之后将其进行打包成***.zip的格式.
运行具有调度依赖关系的job任务的时候
第一个job任务如下,命名为job1.job:
type=command
command=sh 脚本所在的位置的绝对路径
第二个job任务如下:
type=command
dependencies=job1
command=sh 第二个任务脚本所在的绝对路径
之后将2个任务打包在一个zip压缩包中
上传至azkaban
1.根据业务的需求新建一个project
2.将之前打包好的shell包上传,点击Excute Flow,然后点击Schedule创建定时任务,定时的规则和crontab一致,只不过是可视化的界面而已
3.之后就可以查看是否执行完毕
airflow调度
(需要使用python3.x安装airflow,脚本运行的前置条件)(这里我们依旧使用shell任务进行演示),脚本需要放在AIRFLOWHOME/dags目录下
1.首先我们需要创建一个python文件,导入我们需要使用的类库
2.导入DAG对象,后面也需要实例化DAG对象
FROM airflow import DAG
3.导入BashOperator Operator(这个对象是专门用来执行shell任务的 执行其他任务需要使用别的对应的执行器)
FROM airflow.example_dags.example_bash_operator import dag
FROM airflow.operators.bash import BashOperator
4.接下来我们可以实例化DAG对象,添加我们需要定义的一些参数
FROM datetime import datetime,timedelta
5.defalut_args中定义一些参数,在实例化DAG对象的时候可以使用,我们采用python dic格式进行定义
defalut_args = {
'owner':'airflow', ----拥有者的名称
'start_date':datetime(2022,11,17), ----这里定义的是任第一次执行的时间
'retries':1, ----这里定义的是任务失败重试的次数
'retry_delay':timedelta(mintue=5) ----这里定义的是失败重试的时间间隔,我们这里以5分钟为例
}
dag = DAG{
dag_id = 'mydag_airflow_bash', ----DAG id,可以根据自己的业务定,但是必须完全由字母,下划线和数字组成,否则会报错
defalut_args = defalut_args, ----这里定义的是我们外部定义的python dic格式的参数,我们通过这样的方式将其传入到DAG中
schedule_interval = timedelta(days=1) ----这里定义的是DAG任务运行的频率,我们可以设置天,周,小时,分钟,秒,毫秒,,这里也可以使用crontab表达式直接定义schedule_interval=* * * * *
}
6.接下来我们定指定的task任务,注这里的operator支持很多种类型,我们这里使用的BashOperator,里面可以传入参数,显示传入的参数的优先级最高,会覆盖系统默认的参数
first = BashOperator(
task_id='first',
bash_command='这里可以定义需要执行的命令或脚本(必须以.sh结尾),脚本的最后必须要加一个空格,不管后面有没有定义参数必须要加 否则会出现找不到脚本的错误',
dag=dag )
middle = BashOperator(
task_id='middle',
bash_command='这里定义需要执行的命令或脚本(必须以.sh结尾)',
dag=dag )
last = BashOperator(
task_id='last',
bash_command='这里定义需要执行的命令或脚本(必须以.sh结尾)',
dag=dag )
设置task之间的依赖关系,有2种方式
使用set_upstream,set_downstream来设置依赖关系,注意不能出现环形链路,否则会出错
middle.set_upstream(first) ----middle会在first执行完毕之后执行
last.set_upstream(middle) ----last会在middle执行完毕之后执行
可以使用位移符来设置依赖关系(这种方式看起来比较简单一点)
first >> middle >> last ----first先执行,middle次之,last最后
first >> [middle,last] ----first先执行,middle和last并行执行
最终形成的python配置文件如下
FROM airflow import DAG
FROM airflow.example_dags.example_bash_operator import dag
FROM airflow.operators.bash import BashOperator
FROM datetime import datetime,timedelta
defalut_args = {
'owner':'airflow',
'start_date':datetime(2022,11,17),
'retries':1,
'retry_delay':timedelta(mintue=5)
}
dag = DAG{
dag_id = 'mydag_airflow_bash',
defalut_args = defalut_args,
schedule_interval = timedelta(days=1)
}
first = BashOperator(
task_id='first',
bash_command='这里可以定义需要执行的命令',
dag=dag )
middle = BashOperator(
task_id='middle',
bash_command='这里定义需要执行的命令',
dag=dag )
last = BashOperator(
task_id='last',
bash_command='这里定义需要执行的命令',
dag=dag )
first >> middle >> last
1.将上面的python配置文件上传至AIRFLOWHOME/dags目录下,默认的AIRFLOWHOME为安装节点的/root/airflow目录,需要注意的是dags这个目录是需要自己手动创建的
2.之后重新启动airflow(使用ps aux|grep webserver或者是ps aux|grep scheduler)找到对应的airflow进程,进行重新启动
注:在实际生产环境种,脚本任务可能会涉及多个不同的节点,这里我们可以使用SSHOpeator来调用远程机器上面的脚本需要注意的点有以下几点
3.因为SSHOpeator调用远程机器的脚本的时候并不会去读取机器上面的配置文件,因此我们需要在调用的脚本里面添加如下的配置
Ubunto系统
. ~/.profile
Centos或者是Redhat系统
. ~/.bashrc
常见的配置如下
1.ssh_conn_id(str):ssh连接id,名称自取,需要在airflow webserver界面进行配置
2.在使用SSHOpeator之前需要安装对应的SSH包 --首先停止airflow的任务以及界面 --切换到对应的节点,并在合适的python环境下面安装ssh Conenction
操作可按照下面来:
1.切换pyhton环境:
conda activate python**
--安装ssh provider package:
pip install apache-airflow-providers-ssh==2.2.1
2.之后启动airflow:
airflow webserver --port ****
3.配置SSH Conenction连接:
---首先我们需要airflow webui
---之后选择admin
---之后选择connection
---点击'+'新建
---在弹出页面添加coonid(对应ssh_conn_id),conn type选择SSH, Host填远程节点的host地址,username填远程节点的用户名,password填对应用户名的密码,配置远程节点默认连接断口22
4.之后只要使用对应的SSHOperator就可以连接配置中写的远程服务器,如果在配置中填写了remote_host,则会替换web界面配置的连接
5.同样的通过HiveOperator可以直接操作hiveSQL,HiveOperator的参数有
6.hql:需要执行的sql语句
7.hive_cli_conn_id:连接hive的id,同样的也是在webui界面的connection位置进行配置
常见的配置如下
1.想要在airflow上面使用HiveOperator调度任务,首先需要下载依赖并配置Hive MetaStore
操作可按下面的来:
1.切换pyhton环境:
conda activate python**
2.安装hive provider package:
pip install apache-airflow-provider-hive==2.0.2
3.之后启动airflow:
airflow webserver --port ****
4.之后再同样的位置设置hive MetaStore
5.配置conn_id对应的是配种写的hive_cli_conn_id
6.conn type选择hive metastore thrift
7.Host填写hive的服务端host
8.schama读取hive时候 使用的库
9.port填写hive metastore的服务端口