背景
前段時間利用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
# 配置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配置文件
-
關於spark的配置文件可以參考{% post_link Docker構建Spark並提交WordCount任務%},我把上一篇的openjdk換成oraclejdk,openjdk在編譯azkaban時有ssl問題。
-
配置build.gradle
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鏡像倉庫,速度可以快一些。
-
配置commonprivate.properties
execute.as.user=false
memCheck.enabled=false
配置Azkaban執行任務時不檢查內存,azkaban默認執行job會檢查內存是否大於3G,docker部署的容器默認沒有分配這麼多內存,所以如果沒有配置不檢查內存,執行任務可能會失敗。
構建鏡像
老規矩,cd切換到對應的目錄,執行時間可能比較長,因爲編譯azkaban需要下載jar。我在Dockerfile配置中跳過了azkaban測試,不然時間更長。
docker build -t hou/az-so-spark .
啓動容器
這裏啓動容器設置了網絡和Hadoop集羣一個網段,方便調用hdfs
docker run -dit --name az-so-spark --hostname az-so-spark --net hadoop hou/az-so-spark
啓動Azkaban和Spark
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進程
jps -l
可以看到如圖
任務調度
spark程序
用上一次部署spark時用的wordcount程序
編寫Azkaban腳本
# 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
上傳壓縮包
azkaban這裏壓縮包格式要用zip,點擊剛纔創建好的項目,然後點擊upload
執行和查看結果
- 執行
我選擇了實時執行,這裏也可以選擇schedule,設置定時任務執行 - 查看結果
我的這裏因爲一開始沒有配置不檢查內存,所以有兩次失敗的記錄