Azkaban
What is Azkaban
Azkaban is a distributed Workflow Manager, implemented at LinkedIn to solve the problem of Hadoop job dependencies. We had jobs that needed to run in order, from ETL jobs to data analytics products.
Azkaban是一个分布式工作流管理器,在LinkedIn上实现,以解决Hadoop作业依赖性问题。 从ETL工作到数据分析产品,我们需要按顺序运行的工作。
Azkaban consists of 3 key components:
Relational Database (MySQL)
AzkabanWebServer
AzkabanExecutorServer
azkaban的安装使用(任务调度):azkaban-3.56.0
安装注意事项:
1)azkaban编译完成后得到以下文件:
web-server: azkaban-web-server-0.1.0-SNAPSHOT.tar.gz
exec-server: azkaban-exec-server-0.1.0-SNAPSHOT.tar.gz
db数据库脚本: azkaban-db-0.1.0-SNAPSHOT.tar.gz
hadoop-security-plugin: azkaban-hadoop-security-plugin-0.1.0-SNAPSHOT.tar.gz
2)将azkaban.propertities配置文件中对应设置的mysql数据库初始化(库:azkaban)
如果需要给数据库新建用户那么需要给其赋权(也可用root,即不需要以下授权步骤)
(2-1) 新建用户
create user azkaban identified by 'azkaban';
(2-2) 授权
grant all privileges on azkaban to 'azkaban'@'%'identified by 'azkaban'
with grant option;
flush privileges;
mysql密码设置
set global validate_password_policy=LOW;
set global validate_password_length=6;
3)安装部署配置
(3-1) 新建目录作为azkaban的安装目录
(3-2) web-server
- 解压 azkaban-web-server-0.1.0-SNAPSHOT.tar.gz,
修改conf/azkaban.properties ——对应的数据库以及用户密码等
(3-3) execserver
- 解压 azkabanexecserver0.1.0SNAPSHOT.tar.gz
修改conf/azkaban.properties ——对应的数据库以及用户密码等
(3-4) db
- 解压 azkabandb0.1.0SNAPSHOT.tar.gz
执行数据库初始化工作 在azkaban库下:
SOURCE /opt/app/azkaban-3.56.0/azkaban-db-0.1.0-SNAPSHOT/create-all-sql-0.1.0-SNAPSHOT.sql
注意此时执行查询select * from executors;
active=0需要更新设置active=1有效:update executors set active =1 where id = 1;
(3-5) 启动服务
- azkaban执行器(先启动)
$ azkaban_home/exec server/bin/start exec.sh
- azkaban服务器
$ azkaban_home/web server/bin/start web.sh
(3-6)如何停止执行器服务
不要执行$AZKABAN_HOME/execserver/bin/shutdownexec.sh,否则
azkaban会将active=0为无效,要采用KILL 9 pid方式
azkaban的使用出现的问题:
1)job资源打包目前只能是zip格式
2)提交的job任务中如果是在spark框架下使用到hive,那么需要spark-hive的集成(可有多种方式,下面的方式相对简单 https://www.cnblogs.com/juncaoit/p/6545092.html)
(2-1)将hive-site.xml拷贝到spark应用的classpath:${SPARK_HOME}/conf
(2-2)使用hive-site.xml配置的方式
配置hive.metastore.uris:
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop03:9083</value>
<description>指向的是运行metastore服务的主机,这是hive客户端配置,metastore服务不需要配置</description>
</property>
(2-3)SparkSQL通过连接hive提供的metastore服务来获取hive表的元数据,直接启动hive的
metastore服务即可完成SparkSQL和Hive的集成:$ hive --service metastore &
(2-4)可直接在spark/bin下启动spark-sql进行hive的操作
3)提交任务到azkaban执行的时候需注意版本不同的jar包问题,出现以下问题:
ls: cannot access /home/hadoop/spark-2.2.0-bin-hadoop2.6/lib/spark-assembly-*.jar: No such file or directory
出现这个问题的原因是:
spark升级到spark2以后,原有lib目录下的大JAR包被分散成多个小JAR包,原来的spark-assembly-*.jar已经不存在,所以hive没有办法找到这个JAR包。
解决办法:
打开hive的安装目录下的bin目录,找到hive文件,改为以下即可:
#add Spark assembly jar to the classpath
if [[ -n "$SPARK_HOME" ]]
then
sparkAssemblyPath=`ls ${SPARK_HOME}/jars/*.jar`
CLASSPATH="$ {CLASSPATH}: ${sparkAssemblyPath}"
fi
4)若提交的任务中涉及到动态分区问题,需要在sql语句顶部加入设置动态分区的设置:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
5)如果在执行azkaban任务的时候一直处于running状态但是不报错,这个时候需要考虑azkaban是否在执行任务之前进行运行环境的内存检查
修改这个配置:
/opt/app/azkaban-3.56.0/exec-server/plugins/jobtypes/commonprivate.properties 添加:
#系统运行前时不检查内存
memCheck.enabled=false
因为:azkaban默认要求机器是3G及以上的,我们很多情况的vps都达不到这个水平,我们必须修改这个配置,否则任务将一直为running状态!
6)执行azkaban上传的ods层查询导入dw层然后写入hdfs文件的时候报错:
08-04-2019 20:47:55 CST ods_dw INFO - 2019-04-08 20:47:55 ERROR KeyProviderCache:87 - Could not find uri with key [dfs.encryption.key.provider.uri] to create a keyProvider !!
08-04-2019 20:48:20 CST ods_dw INFO - Response code
08-04-2019 20:48:27 CST ods_dw INFO - Error in query: Table or view not found: user_action_appdownload; line 3 pos 105
08-04-2019 20:49:12 CST ods_dw INFO - Process completed unsuccessfully in 348 seconds.
08-04-2019 20:49:12 CST ods_dw ERROR - Job run failed!
java.lang.RuntimeException: azkaban.jobExecutor.utils.process.ProcessFailureException
发现hql语句中少加了表对应的库,最好在shell脚本以及hql中的表写全库名,规范,在执行脚本的时候能够无论在什么位置都能找到对应库下的表
Demo
demo:使用azkaban提交任务执行查询导入
1)启动相关进程和服务(需要用到spark和hive集成,所以HDFS和YARN进程都需要,将hive --servie metastore元数据服务打开,启动azkaban执行以及web进程)
2)提前在需要导入的hive对应的库下创建和需要导入数据字段对应的字段的表
create table if not exists program1_dw.user_action_launch (
action string,
deviceid string,
userid string,
os string,
osversion string,
manufacturer string,
carrier string,
networktype string,
ct bigint
)partitioned by (bdp_day string) stored as parquet;
3)关于需要提交到azkabn运行的zip包中的依赖文件(flow-1.0):
azkaban首先在提交的zip包中找到.job文件,然后根据文件中的各种依赖找到对应的其余文件执行操作
(3-1)action_launch.job文件内容如下:
#spark job on yarn
type=command
command=sh action_launch.sh
#success.emails=xx@email.com
#failure.emails=xx@email.com
#notify.emails=xx@email.com
(3-2)action_launch.sh文件内容如下:
#!/bin/bash
#params
partitions=80
#bdp_day=`date -d "-1 day" +"%Y%m%d"`
bdp_day=20190101
action=launch
#spark sql job
/opt/app/spark-2.3.1-bin-hadoop2.7/bin/spark-sql \
--master yarn \
--name action_launch_job \
--S \
--hiveconf partitions=$partitions \
--hiveconf bdp_day=$bdp_day \
--hiveconf action=$action \
--num-executors 4 \
--executor-memory 1G \
--executor-cores 2 \
-f action_launch.hql
(3-3)action_launch.hql文件内容如下:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table program1_dw.user_action_launch partition(bdp_day)
select
action,
deviceid,
userid,
os,
osversion,
manufacturer,
carrier,
networktype,
ct,
bdp_day
from program1_ods.user_action_log
where
bdp_day = '${bdp_day}'
and
action = '${action}';