Docker部署Azkaban Solo模式调度Spark

背景

前段时间利用Docker部署了hadoop集群和spark,也简单的提交了任务。但是肯定有一个疑问,如果我们要执行定时任务怎么办呢?或者我们执行复杂的具有顺序的多任务怎么办?在大数据中,这种场景非常常见,一个大数据任务通常由大量的任务组成,并且可能是shell脚本、mapreduce任务、spark任务等,并且任务之间存在依赖关系。手动执行这种原始办法虽然可以,但是人总有出错的时候。今天要带来的一款具有复杂任务调度能力的框架-Azkaban,也支持定时调度。

Azkaban介绍

Azkaban是由Linkedin开源的一个批量工作流任务调度器

Azkaban特点
  • 兼容任何版本的hadoop
  • 易于使用的Web用户界面
  • 简单的工作流的上传
  • 方便设置任务之间的关系
  • 调度工作流
  • 模块化和可插拔的插件机制

  • 认证/授权(权限的工作)

  • 能够杀死并重新启动工作流
  • 有关失败和成功的电子邮件提醒

上面的描述太抽象?一个技术要想了解,必须得自己捣鼓一下,接下来我将用Docker来部署,Docker用来学习安装软件不要太舒服,一来它可以很方便的给你提供Linux环境,二来不用将软件装在自己电脑上,久而久之电脑变得很卡特别是win环境。

Docker部署Azkaban

环境准备
  • 宿主机系统:win10
  • hadoop版本:3.1.1(构建基于HDFS的spark)
  • Spark版本:2.4.5
  • 容器系统:ubuntu16
  • jdk:oraclejdk1.8.0.251
  • azkaban:开发版
配置Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 配置ssh免密登陆
RUN ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' && \
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 复制jdk和配置jdk环境
RUN mkdir /usr/lib/jvm/
ADD jdk-8u251-linux-x64.tar.gz /usr/lib/jvm/
ENV JAVA_HOME /usr/lib/jvm/jdk1.8.0_251/
ENV PATH $PATH:$JAVA_HOME/bin

# 复制hadoop和配置hadoop配置
RUN mkdir /usr/local/hadoop/
ADD hadoop-3.1.1.tar.gz /usr/local/hadoop/
ENV HADOOP_HOME /usr/local/hadoop/hadoop-3.1.1
ENV PATH $PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

# 复制spark和配置spark环境
RUN mkdir /usr/local/spark
ADD spark-2.4.5-bin-without-hadoop.tgz /usr/local/spark
ENV SPARK_HOME=/usr/local/spark/spark-2.4.5-bin-without-hadoop
ENV PATH=$PATH:$SPARK_HOME/bin
ENV SPARK_MASTER_PORT 7077
ENV SPARK_MASTER_WEBUI_PORT 8080
ENV SPARK_MASTER_LOG /tmp/logs
ENV SPARK_WORKER_LOG /tmp/logs
ENV SPARK_VERSION 2.4.5

COPY config/* /tmp/
RUN mv /tmp/spark-config.sh $SPARK_HOME/sbin && \
mv /tmp/spark-env.sh $SPARK_HOME/conf

# 安装git
RUN apt-get update && apt-get install -y git
RUN git clone https://github.com/azkaban/azkaban.git /usr/local/azkaban && \
mv /tmp/build.gradle /usr/local/azkaban && \
/usr/local/azkaban/gradlew build installDist -x test && \
mv /tmp/commonprivate.properties /usr/local/azkaban/azkaban-solo-server/build/install/azkaban-solo-server/plugins/jobtypes

EXPOSE 8080 7077 6066 8081

CMD [ "sh", "-c", "service ssh start; bash"]
azkaban配置文件
  1. 关于spark的配置文件可以参考Docker部署Spark并提交WordCount任务,我把上一篇的openjdk换成oraclejdk,openjdk在编译azkaban时有ssl问题。

  2. 配置build.gradle

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    buildscript {
    repositories {
    maven {
    url 'https://maven.aliyun.com/nexus/content/groups/public/'
    }
    mavenCentral()
    }
    dependencies {
    classpath 'com.cinnober.gradle:semver-git:2.2.3'
    classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.14'
    }
    }

    allprojects {
    apply plugin: 'jacoco'

    repositories {
    maven {
    url 'https://maven.aliyun.com/nexus/content/groups/public/'
    }
    mavenLocal()
    mavenCentral()
    }
    }

    拷贝一份build.gradle文件修改maven仓库地址,这里是为了gradle构建azkaban项目时,配置国内maven镜像仓库,速度可以快一些。

  3. 配置commonprivate.properties

    1
    2
    execute.as.user=false
    memCheck.enabled=false

    配置Azkaban执行任务时不检查内存,azkaban默认执行job会检查内存是否大于3G,docker部署的容器默认没有分配这么多内存,所以如果没有配置不检查内存,执行任务可能会失败。

构建镜像

老规矩,cd切换到对应的目录,执行时间可能比较长,因为编译azkaban需要下载jar。我在Dockerfile配置中跳过了azkaban测试,不然时间更长。

1
docker build -t hou/az-so-spark .
启动容器

这里启动容器设置了网络和Hadoop集群一个网段,方便调用hdfs

1
docker run -dit --name az-so-spark --hostname az-so-spark --net hadoop hou/az-so-spark
启动Azkaban和Spark
1
2
3
4
5
6
7
8
docker exec -it az-so-spark /bin/bash
# 启动spark
/usr/local/spark/spark-2.4.5-bin-without-hadoop/sbin/start-all.sh
# 检查spark是否启动成功,看是否有spark master和worker进程
jps -l
# 启动azkaban 务必要在该目录下启动,我第一次在bin目录下启动,启动不了,会报找不到数据库配置错误
cd azkaban-solo-server/build/install/azkaban-solo-server
bin/start-solo.sh
检查azkaban和spark进程
1
jps -l

可以看到如图

img

任务调度

spark程序

用上一次部署spark时用的wordcount程序

编写Azkaban脚本
1
2
3
# wordCount.job
type=command
command=/usr/local/spark/spark-2.4.5-bin-without-hadoop/bin/spark-submit --class com.hou.test.WordCountJob --master local study.word.count-1.0-SNAPSHOT.jar

可以看到azkaban的command type调度本质上是执行shell命令

压缩打包zip

将study.word.count-1.0-SNAPSHOT.jar和wordCount.job文件打包为zip格式

创建项目

登录azkaban管理后台,默认端口8081,name和password默认都是azkaban,首页点击create project

img

上传压缩包

azkaban这里压缩包格式要用zip,点击刚才创建好的项目,然后点击upload

img

执行和查看结果
  1. 执行

    img

    我选择了实时执行,这里也可以选择schedule,设置定时任务执行

  2. 查看结果

    img

    我的这里因为一开始没有配置不检查内存,所以有两次失败的记录