簡介
Azkaban是LinkedIn開源的任務排程架構,類似于JavaEE中的JBPM和Activiti工作流架構。
如ETL的過程,Sqoop在淩晨1點從RDBMS中抽取資料(E),在淩晨2點用Hadoop或Spark轉換資料(T),在淩晨3點用Sqoop再把結果資料加載(L)進RDBMS或NOSQL,假設沒有Azkaban這樣的排程架構,一般用crontab+shell,但crontab+shell雖然簡單易用,但也有明顯的缺點,如任務的依賴處理、任務監控、任務流的可視化等,就需要一個排程架構來統一。
常見的任務排程架構有Apache Oozie、LinkedIn Azkaban、Apache Airflow、Alibaba Zeus,由于Azkaban具有輕量可插拔、友好的WebUI、SLA告警、完善的權限控制、易于二次開發等優點,也得到了廣泛應用。
本文以Azkaban為例,總結Azkaban基本原理,以及三種模式的部署和測試。
Azkaban原理
Azkaban架構
Azkaban三個關鍵元件的作用
Relational Database:存儲中繼資料,如項目名稱、項目描述、項目權限、任務狀态、SLA規則等。
AzkabanWebServer:項目管理、權限授權、任務排程、監控executor。
AzkabanExecutorServer:作業流執行的Server。
Azkaban三種部署模式
solo-server模式
DB使用的是一個内嵌的H2,Web Server和Executor Server運作在同一個程序裡。這種模式包含Azkaban的所有特性,但一般用來學習和測試。
two-server模式
DB使用的是MySQL,MySQL支援master-slave架構,Web Server和Executor Server運作在不同的程序中。
分布式multiple-executor模式
DB使用的是MySQL,MySQL支援master-slave架構,Web Server和Executor Server運作在不同機器上,且有多個Executor Server。
Azkaban三種模式安裝前準備
Azkaban3.x在安裝前需要自己編譯成二進制包。
(1)編譯環境
git => [root@node1 ~]#yum install git
g++ => [root@node1 ~]# yum install gcc-c++
(2)下載下傳源碼&解壓
[root@node1 ~]# wget https://github.com/azkaban/azkaban/archive/3.42.0.tar.gz
[root@node1 ~]# mv 3.42.0.tar.gz azkaban-3.42.0.tar.gz
[root@node1 ~]# tar -zxvf azkaban-3.42.0.tar.gz
[root@node1 ~]# ls
azkaban-. azkaban-..tar.gz
(3)編譯
[root@node1 ~]# cd azkaban-3.42.0
[root@node1 azkaban-.]# ./gradlew build installDist -x test #Gradle是一個基于Apache Ant和Apache Maven的項目自動化建構工具。-x test 跳過測試
(4)編譯後生成的安裝包路徑
[root@node1 azkaban-.]# pwd
/root/azkaban-.
#solo-server模式安裝包路徑
[root@node1 azkaban-.]# ls azkaban-solo-server/build/distributions/
#two-server模式和multiple-executor模式web-server安裝包路徑
[root@node1 azkaban-.]# ls azkaban-web-server/build/distributions/
#two-server模式和multiple-executor模式exec-server安裝包路徑
[root@node1 azkaban-.]# ls azkaban-exec-server/build/distributions/
solo-server模式部署
(1)節點規劃
HOST | 角色 |
---|---|
node1 | Web Server和Executor Server同一程序 |
(2)解壓
(3)配置
[[email protected] ~]# vim /root/azkaban-solo-server-0.1.0-SNAPSHOT/conf/azkaban.properties
default.timezone.id=Asia/Shanghai #修改時區
(4)啟動
[root@node1 ~]# cd /root/azkaban-solo-server-0.1.0-SNAPSHOT/
[root@node1 azkaban-solo-server--SNAPSHOT]# bin/azkaban-solo-start.sh
注:啟動/關閉必須進到/root/azkaban-solo-server-0.1.0-SNAPSHOT/目錄。
(5)驗證是否啟動成功
[root@node1 ~]# jps
AzkabanSingleServer(對于Azkaban solo‐server模式,Exec Server和Web Server在同一個程序中)
通路Web Server=>http://node1:8081/
(6)測試帶有依賴的任務
A、建立job
[[email protected] ~]# mkdir -p azkaban_jobs/solo_job
#在solo_job目錄建立兩個檔案one.job two.job,内容如下
[[email protected] solo_job]# cat one.job
type=command
command=echo "this is job one"
[[email protected] solo_job]# cat two.job
type=command
dependencies=one
command=echo "this is job two"
#打包成zip包
[[email protected] azkaban_jobs]# zip -r solo_job.zip solo_job/
B、Azkaban WebUI建立工程并執行
http://node1:/index登入=>Create Project=>Upload 上一步生成的zip包 =>execute flow執行一步步操作即可
注:在Azkaban項目中,任務的名稱是以最後一個Job名來命名的。
B_1、建立工程
B_2、上傳job zip檔案
B_3、執行
B_4、結果
two-server模式部署
(1)節點規劃
HOST | 角色 |
---|---|
node1 | web‐server和exec‐server不同程序 |
node2 | MySQL |
(2)解壓web‐server和exec‐server
#web-server
[root@node1 ~]# tar -zxvf /root/azkaban-3.42.0/azkaban-web-server/build/distributions/azkaban-web-server-0.1.0-SNAPSHOT.tar.gz -C .
#exec‐server
[root@node1 ~]# tar -zxvf /root/azkaban-3.42.0/azkaban-exec-server/build/distributions/azkaban-exec-server-0.1.0-SNAPSHOT.tar.gz -C .
(3)将Azkaban源碼中的create-all-sql腳本拷貝到Mysql所在節點node2
(4)Mysql上建立對應的庫、增權重限、建立表
mysql> CREATE DATABASE azkaban_two_server; #建立資料庫
mysql> use azkaban_two_server;
mysql> CREATE USER 'azkaban'@'%' IDENTIFIED BY 'azkaban';#建立使用者
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON azkaban_two_server.* to 'azkaban'@'%' WITH GRANT OPTION;#給使用者授權
mysql> source create-all-sql-.-SNAPSHOT.sql;#建立表
(5)生成ssl
[root@node1 ~]# keytool -keystore keystore -alias jetty -genkey -keyalg RSA
注:密碼和最後确認需要輸入,其他預設即可。
(6)設定web‐server
拷貝conf目錄和log4j.properties
[[email protected] ~]# cp -r /root/azkaban-solo-server-0.1.0-SNAPSHOT/conf /root/azkaban-web-server-0.1.0-SNAPSHOT/
[[email protected] ~]# find azkaban-3.42.0 -name 'log4j*'
[[email protected] ~]# cp azkaban-3.42.0/azkaban-web-server/src/test/resources/log4j.properties azkaban-web-server-0.1.0-SNAPSHOT/conf/
[[email protected] ~]# vim azkaban-web-server-0.1.0-SNAPSHOT/conf/azkaban.properties
#需要修改的地方
default.timezone.id=Asia/Shanghai
#database.type=h2
#h2.path=./h2
#h2.create.tables=true
database.type=mysql
mysql.port=
mysql.host=node2
mysql.database=azkaban_two_server
mysql.user=azkaban
mysql.password=azkaban
mysql.numconnections=
jetty.keystore=/root/keystore #keytool生成的keystore路徑
jetty.password= #keytool中設定的密碼
jetty.keypassword=
jetty.truststore=/root/keystore
jetty.trustpassword=
添加azkaban.native.lib=false 和 execute.as.user=false屬性
[root@node1 azkaban-web-server--SNAPSHOT]# mkdir -p plugins/jobtypes
[root@node1 jobtypes]# cat commonprivate.properties
azkaban.native.lib=false
execute.as.user=false
(7)啟動web-serrver并驗證
[root@node1 ~]# cd azkaban-web-server-0.1.0-SNAPSHOT/
[root@node1 azkaban-web-server-.-SNAPSHOT]# bin/azkaban-web-start.sh
驗證:
jps=>AzkabanWebServer
webUI=>http://node1:8081/index
(8)從web-server拷貝conf目錄、plugins目錄并啟動executor‐server
[root@node1 ~]# cd azkaban-exec-server-0.1.0-SNAPSHOT/
[root@node1 azkaban-exec-server-.-SNAPSHOT]# cp -r ../azkaban-web-server-0.1.0-SNAPSHOT/conf/ .
[root@node1 azkaban-exec-server-.-SNAPSHOT]# cp -r /root/azkaban-web-server-0.1.0-SNAPSHOT/plugins/ .
[root@node1 azkaban-exec-server-.-SNAPSHOT]# bin/azkaban-executor-start.sh
(9)測試帶有依賴的任務
注:Hadoop、Spark的指令盡量用全路徑。
A、建立帶有hadoop 和spark 且有依賴的Job
[root@node1 ~]# cd azkaban_jobs/
[root@node1 azkaban_jobs]# mkdir two_server_job
[root@node1 two_server_job]# cat mr.job
type=command
command=hadoop jar /usr/hdp/.-/hadoop-mapreduce/hadoop-mapreduce-examples-...-.jar wordcount /data/mr_test_data.txt /result_mr/
[root@node1 two_server_job]# cat spark.job
type=command
dependencies=mr
command=/usr/hdp/2.6.4.0-91/spark2/bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster --executor-memory 5
M --num-executors /usr/hdp/.-/spark2/examples/jars/spark-examples_2.-...-.jar
[root@node1 azkaban_jobs]# zip -r two_server_job.zip two_server_job/
B、建立工程two_server_dependency上傳zip檔案
C、運作
D、MapReduce Spark運作結果
分布式multiple-executor模式
(1)節點規劃
HOST | 角色 |
---|---|
node1 | web-server、exec-server |
node2 | mysql |
node3 | exec-server |
(2)拷貝exec-server到node3
(3)在node3 exec-server 重新生成keystore
(4)在azkaban web-server中azkaban.properties配置檔案添加配置
#啟用multiple-executor模式
azkaban.use.multiple.executors=true
#在每次分發job時,先過濾出滿足條件的executor,然後再做比較篩選
#如最小剩餘記憶體,MinimumFreeMemory,過濾器會檢查executor空餘記憶體是否會大于6G,如果不足6G,則web-server不會将任務交由該executor執行。可參考Azkaban Github源碼
#如CpuStatus,過濾器會檢查executor的cpu占用率是否達到95%,若達到95%,web-server也不會将任務交給該executor執行。可參考Azkaban Github源碼。
#參數含義參考官網說明http://azkaban.github.io/azkaban/docs/latest/#configuration
#由于是虛拟機,不需要過濾,隻需要比較即可
#azkaban.executorselector.filters=StaticRemainingFlowSize,MinimumFreeMemory,CpuStatus
#某個任務是否指定了executor id
azkaban.executorselector.comparator.NumberOfAssignedFlowComparator=
#記憶體
azkaban.executorselector.comparator.Memory=
#最後一次被分發
azkaban.executorselector.comparator.LastDispatched=
#CPU
azkaban.executorselector.comparator.CpuUsage=
(4)在azkaban_two_server庫executors表中添加executor
mysql> insert into executors(host,port,active) values("192.168.222.101",,);
mysql> insert into executors(host,port,active) values("192.168.222.103",,);
注:這裡把active設定為(激活狀态)。
(5)啟動node1 web-server、node1 exec-server、node3 exec-server
先啟動exec-server,再啟動 web-server
(6)建立工程名multiple-executor上傳job檔案
#solo_job.zip檔案内容
one.job 内容
type=command
command=echo "this is job one"
two.job 内容
type=command
dependencies=one
command=echo "this is job two"
(7)關閉node1 上的exec-server 執行job
可以看到,在node1 exec關閉後,任務被送出到了node3 exec,最終執行成功。
同理,關閉node3 exec,任務會被排程到node1 exec。
Azkaban 企業級部署HA
Azkaban WebServer挂掉,不影響已經送出的任務執行,主要是不能通過WebUI檢視Job、管理Job、跟蹤Job狀态。
是以,對于這個架構,主要是要解決MySQL HA和ExecutorServer HA。官方支援ExecutorServer HA,我們隻需要配一個MySQL HA就行了。