ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Azkaban 3.x启动全流程:从环境准备到双节点部署

Azkaban 3.x启动全流程:从环境准备到双节点部署 1. Azkaban是什么为什么要用它1.1 工作流调度器在Hadoop生态中的位置接触Hadoop一段时间后你会发现真正生产中跑数据绝不是手动在命令行敲几条指令那么简单。一个完整的离线数仓项目往往有成百上千个任务——凌晨两点清洗日志、凌晨三点同步业务库、凌晨四点半跑指标、早上七点导出报表。这些任务之间有严格的前后依赖关系A任务没跑完B任务就不能启动。单靠crontab硬写排错时你会怀疑人生。Azkaban就是解决这个问题的。它是LinkedIn开源的工作流调度器在Hadoop生态里扮演的是“大管家”角色负责把零散的MapReduce、Spark、Hive脚本、Shell命令组织成有依赖关系的工作流按预设时间自动触发失败还能自动重试、发告警。和同为调度器的Oozie、Airflow相比Azkaban最大的特点就是轻量——部署简单、Web界面直观、按项目管理Job的方式很符合工程习惯所以很多中小团队至今还在用。1.2 这篇文章能帮你解决什么我在指导新人搭Hadoop环境时发现很多人卡住的不是Azkaban的Job怎么写而是这玩意儿启动不起来。报错五花八门数据库连不上、executor没激活、SSL证书不存在、端口被占……网上资料又老又碎Azkaban 2.x和3.x的启动方式还不一样照着老教程操作越弄越乱。这篇文章就围绕“Azkaban的启动”这条主线把从环境准备、数据库初始化、配置修改到双节点启动全流程捋一遍。我用的方案是基于Azkaban 3.x、以MySQL作为元数据库、在Hadoop集群含伪分布式环境下的标准部署方式。Hadoop本身怎么装、伪分布式怎么搭这里不展开默认你已经把NameNode和DataNode跑起来了。实验环境是CentOS 7、JDK 8、Hadoop 2.x/3.x都适用。2. 启动前必须想清楚的几件事2.1 Azkaban 3.x的架构先弄清要启动几个进程Azkaban 3.x和老的2.x有个关键区别2.x时代只有一个AzkabanWebServer进程把调度和执行都包了3.x拆成了两个——AzkabanWebServerWeb服务负责界面、项目管理、权限和AzkabanExecutorServer执行服务负责任务真正跑起来。这两个进程可以部署在同一台机器也可以跨机器分布式部署生产环境一般是分开的、执行节点可以横向扩容。你第一次实验的话全部装在一台机器上就行但必须理解你要启动的是两个独立进程不是只跑一个脚本就完事。这两个进程之间靠MySQL数据库通信。Web节点往数据库的executor表里注册执行节点信息提交任务时把任务包放到数据库里排队Executor节点主动去拉取任务来执行执行状态再写回数据库。所以数据库是它们之间的“消息中间件”数据库挂了、连不上、表结构不对启动就会出各种奇奇怪怪的错。2.2 版本选择和Java环境这一步偷懒后面全是坑Azkaban版本很绕GitHub上发布包命名也不统一有azkaban-3.x.x.tar.gz这种整体包也有分开的azkaban-exec-server、azkaban-web-server独立包。我直接推荐去GitHub的Azkaban Releases页面下载azkaban-3.90.0或更新的3.x版本里面是打包好的独立模块。Java环境必须是JDK 8别用JDK 11或17来跑Azkaban 3.x对JDK 8支持最稳。这个我实测过用JDK 11启动表面上能起来但执行任务时会出现一些Java反射相关的兼容问题排查起来非常隐蔽。如果你机器上有多版本JDK建议在启动脚本里显式指定JAVA_HOME。Azkaban还需要MySQL 5.7或8.0生产环境建议独立实例实验环境可以和Hadoop的元数据库共用一台MySQL但最好单独建库别跟Hive的metastore混在一起方便排查问题。JDBC驱动这块如果MySQL是5.7用mysql-connector-java 5.1.49如果是8.0用8.0.x的驱动记得把jar包放到Azkaban各模块的lib目录下。注意Azkaban 3.x默认启用SSLHTTPS协议所以启动前要准备一个Java的keystore证书文件。这是新人最容易忽略的点本地方案可以用JDK自带的keytool工具生成自签名证书后面会给出具体命令。2.3 规划好目录和端口给后续排错留条后路部署前先把目录规划好我的习惯是统一放到/opt/azkaban下面/opt/azkaban ├── azkaban-web-server-3.x.x # Web模块目录 ├── azkaban-exec-server-3.x.x # Executor模块目录 └── server # 存放启动脚本、日志端口规划这里讲清楚默认配置下Web服务监听80813.xExecutor服务监听12321。如果你改过配置务必记住这两个端口后面排查“启动成功但访问不了”的时候第一反应就应该是查端口监听状态。3. 数据库初始化和SSL配置启动前最关键的准备3.1 建库建表一个命令把元数据表全部弄好Azkaban发布包里自带建表SQL脚本在azkaban-db目录或者执行模块的sql目录下文件名一般是create-all-sql-3.x.x.sql。这个脚本会创建所有需要的表projects、project_files、execution_flows、executors、triggers等等。连接MySQL执行前先手动创建一个独立的数据库mysql -uroot -p mysql CREATE DATABASE azkaban DEFAULT CHARACTER SET utf8mb4; mysql GRANT ALL PRIVILEGES ON azkaban.* TO azkaban% IDENTIFIED BY 你的密码; mysql FLUSH PRIVILEGES; mysql EXIT;然后用Azkaban专用的MySQL账号导入表结构。这里有一个细节别用root去跑Azkaban连接权限太大是一方面另一方面是后续排查问题时分不清到底是应用配置问题还是数据库权限问题。单独建一个账号权限只给azkaban这个库是更规范的做法。mysql -uazkaban -p azkaban /opt/azkaban/azkaban-db/create-all-sql-3.90.0.sql导入完了检查一下show tables能看到几十张表就说明脚本执行正常。其中最关键的是executors表它记录executor节点的注册信息和激活状态Azkaban启动后能不能正常调度就看这张表里有没有被标记为激活的executor记录。3.2 生成SSL证书并完成双向配置Azkaban 3.x的Web服务默认以HTTPS方式提供但安装包里不会帮你生成证书需要自己用keytool生成一个keystore。这一步对实验环境来说纯粹是为了能让服务启动起来证书有效期的配置建议设长一点省得几个月后突然访问不了排查半天发现是证书过期了。keytool -genkeypair -alias azkaban -keyalg RSA -keystore /opt/azkaban/keystore \ -storepass 你的密码 -keypass 你的密码 -dname CNlocalhost, OUdev, Otest, Lbeijing, STbeijing, CCN \ -validity 3650生成后把这个keystore路径分别配置到web和executor两个模块的azkaban.properties里。两边都要配不是只配Web端。Executor虽然没有页面给你访问但它在集群内部也会用HTTPS协议通信不配就会报SSL握手失败的错误。很多教程只提Web要配导致Executor启动报错这个坑我踩过特意写出来。最后还要在MySQL里确认一下executors表的情况。这个表在创建时是空的第一次启动executor进程后它会自动把自己插入这张表。有的版本设计中executor字记录默认是激活状态有的则需要手工设置。保险做法是等executor启动后在MySQL里查一下SELECT id, host, port, active FROM azkaban.executors;如果active为0执行UPDATE azkaban.executors SET active1 WHERE id1;把它激活。4. 动手启动从配置修改到双节点拉起4.1 web和executor的azkaban.properties核心配置解读安装包解压后conf目录下的azkaban.properties是唯一需要重点改的配置文件。这个文件决定了进程怎么连数据库、用什么端口、日志级别等一堆行为。Executor模块的azkaban.properties必改项是这几行# MySQL连接 database.typemysql mysql.port3306 mysql.hostlocalhost mysql.databaseazkaban mysql.userazkaban mysql.password你的密码 mysql.numConnections10 # Executor服务端口 executor.port12321 # Azkaban内部Jetty Server设置3.x必须有否则启动起不来 jetty.use.ssltrue jetty.maxThreads25 jetty.ssl.port8443这里重点解释jetty.ssl.port。3.x版本的Executor会把内部通信端口分成两个一个是executor.port负责接收Web发来的任务请求一个是jetty.ssl.port负责HTTPS状态上报。很多教程只让你改executor.port结果Executor启动时直接报“port cannot be empty或者SSL相关错误”就是因为这个内部Jetty端口没配置。Web模块的azkaban.properties核心配置如下# Jetty服务器端口浏览器访问的就是它 jetty.port8081 jetty.use.ssltrue jetty.keystore/opt/azkaban/keystore jetty.password你的密码 jetty.keypassword你的密码 jetty.truststore/opt/azkaban/keystore jetty.trustpassword你的密码 # MySQL连接和executor里配置保持一致 mysql.hostlocalhost mysql.databaseazkaban mysql.userazkaban mysql.password你的密码 # 邮件通知配置不发邮件可以不配 mail.sender mail.host mail.user mail.password另外还有一个重要配置项是azkaban.name和azkaban.label在Web的properties文件里可以随便设置成你自己的项目名显示在网页左上角。不配也能启动但配了之后在浏览器上看部署效果会很直观比如azkaban.nameMyAzkaban。4.2 启动Executor注意启动顺序和日志观察一定要先启动Executor再启动Web。因为Web启动过程会去MySQL里查询激活状态的executor记录如果Executor还没注册进来Web会直接报错退出或者界面显示“no active executor”。启动方式很简单进入executor模块目录执行cd /opt/azkaban/azkaban-exec-server-3.90.0 ./bin/start-exec.sh启动后不要急着访问先等三到五秒然后看日志。日志文件在logs/目录下文件名一般是executor.log。用下面这个命令持续跟踪输出tail -f logs/executor.log日志里出现Starting executor字样后关键要确认后面有没有跟着报错信息。正常情况会看到类似Scheduler started. Azkaban Executor Server started on port 12321这意味着Executor启动成功。然后用jps验证进程jps | grep Azkaban AzkabanExecutorServer能看到AzkabanExecutorServer字样就说明JVM进程活着。接着去MySQL里确认executor注册SELECT id, host, port, active FROM azkaban.executors;看到一条host为本机IP、port为12321的记录。如果你的记录active是0执行UPDATE azkaban.executors SET active1 WHERE id1;这个激活操作非常关键很多教程没提导致后续Web启动成功但提交任务一直停留在preparing状态。我特意把这条SQL写在操作步骤里就是因为它太容易被漏掉。4.3 启动Web服务并验证页面Executor稳定运行后再启动Webcd /opt/azkaban/azkaban-web-server-3.90.0 ./bin/start-web.sh同样观察web.log日志tail -f logs/web.log看到类似下面这行就说明Web起来了Azkaban Web Server started on port 8081验证方式两步走先确认进程和端口浏览器访问https://服务器IP:8081看到登录界面就成功了一大半。jps | grep Azkaban ss -tlnp | grep -E 8081|12321浏览器访问时因为用的是自签名证书浏览器会弹“不安全”警告直接点“高级”然后“继续前往”即可。默认登录账号是azkaban默认密码是azkaban。如果你在properties里没有配user.manager.xml.fileWeb界面会用默认的admin账号。登录成功后建议立刻验证一遍端到端流程新建一个project创建一个测试JobJob内容可以极简比如# test.job typecommand commandecho hello azkaban然后用Web界面的“Upload”按钮把这个.job文件打包成zip上传再定时执行一次“Execute Flow”观察任务能否从preparing走到success。能走到这一步整个Azkaban的启动工作就彻底闭环了后面写复杂的工作流都有基础。4.4 生产环境建议用脚本管理启动、停止与自启动实验模式下手动启动没问题但Azkaban在生产中使用时最好用脚本统一管理启停。我自己的服务器上会写一个简单的shell脚本放在/opt/azkaban/server/目录下#!/bin/bash # azkaban-ctl.sh 管理脚本 case $1 in start) /opt/azkaban/azkaban-exec-server-3.90.0/bin/start-exec.sh /opt/azkaban/azkaban-web-server-3.90.0/bin/start-web.sh ;; stop) /opt/azkaban/azkaban-web-server-3.90.0/bin/shutdown-web.sh /opt/azkaban/azkaban-exec-server-3.90.0/bin/shutdown-exec.sh ;; status) jps | grep -E Azkaban(Web|Executor)Server ;; *) echo Usage: $0 {start|stop|status} exit 1 ;; esac放到/etc/rc.local里或者用systemd定义service就能实现开机自启。生产上这么做最大的好处是重启服务器后不用手动一个个起进程而且用脚本统一管理ABC任务的启停顺序不容易搞错。5. 常见启动失败问题我踩过的坑全在这里5.1 Executor启动报数据库连接错误这个报错可能是数据库连接配置不对、网络不通或者驱动缺失。最常见的原因是mysql.connector这个Java类找不到也就是驱动jar包没放对位置。Azkaban 3.x各模块的lib目录下要放对应的mysql-connector-java-x.x.x.jar如果你从发布包解压后没额外处理过lib目录下很可能没有这个jar需要手动从Maven仓库或MySQL官网下载放进去。另一个是时区问题8.x驱动连接MySQL时默认要求指定serverTimezone否则会报Could not create connection to database server。解决方案很直接在JDBC连接串或数据库配置中加上serverTimezoneAsia/Shanghai参数或者把MySQL全局时区改成08:00。这个坑在MySQL 8.0环境很常见我排过一次排查了半小时才反应过来是时区。5.2 Web启动报错提示找不到active executor这个报错的现象是Web进程能启动但提交任务时一直pending或者在日志里看到“no active executor found”。原因就是我前面反复强调的——executors表里没有active状态为1的记录或者Executor注册的IP和Web访问的IP不一致。排查思路先确认Executor已经启动然后看executors表里的host字段。这里有个隐蔽的情况Executor注册时用的是本机配置的executor.host如果配置文件里没显式指定它会自动获取本机网卡IP。如果是云服务器自动获取的可能是内网IP而Web节点在另一台机器上就访问不到它。解决办法是在executor的properties里显式设置executor.host对外可访问的IP然后删掉旧记录重启Executor让它重新注册。5.3 页面能打开但登录后界面一直转圈出现这个情况的概率不高但非常让人头疼。页面能打开说明Web进程起来了登录后转圈说明前端请求后端接口超时了多数是Executor和Web之间的HTTPS通信出了问题。重点检查executor模块的azkaban.properties里有没有配置jetty.ssl.port还有keystore路径和密码是否正确。还有一点容易被忽略Web在访问Executor时会去MySQL的executors表里拿host和port如果host是localhost而Web和Executor在同机器上还好一旦不在同一台机器必须改为真实可达的IP。5.4 端口被防火墙拦了启动成功但访问不了这个问题在实验环境下也很常见。明明jps里有进程日志显示启动成功但浏览器就是访问不了。第一反应查本机端口监听ss -tlnp | grep 8081显示LISTEN状态后接下来就是防火墙的事。CentOS 7默认firewalld开启了需要放行端口firewall-cmd --permanent --add-port8081/tcp firewall-cmd --permanent --add-port12321/tcp firewall-cmd --reload云服务器的话还要去安全组里把这两个端口加上白名单。这个属于环境问题跟Azkaban本身无关但新手排查时很容易卡在这里以为配置有问题实际上防火墙就全挡了。5.5 常见问题速查表现象直接原因排查手段Executor启动即退出数据库连不上或驱动缺失检查mysql连接串、驱动jar、MySQL服务状态Executor启动报SSL错误jetty.use.ssl未配或keystore路径错误检查properties中ssl相关配置Web启动报no active executorexecutors表没有激活记录执行UPDATE激活executor页面打不开防火墙或安全组未放行端口ss查监听、firewall-cmd放行提交任务后一直preparingexecutor的host不可达检查executors表host字段是否为真实IP6. 启动成功的验证手段与后续扩展6.1 一套标准的“体检流程”判断Azkaban状态正常启动完成不等于配置正确。我在验收一套新部署的Azkaban环境时有一套固定的“体检流程”照着走一遍基本能确认系统是健康的先看进程jps里Web和Executor两个进程有一个缺失都算异常再看端口8081和12321都必须处于监听状态再看数据库executors表要有且只有一条active为1的记录最后跑一个测试Job从Web界面上传最小zip包确认任务能正常执行成功。这套流程熟练后三分钟就能走完比盲猜问题高效得多。特别是最后一步“跑一个测试Job”建议所有人都不要跳过因为前面所有检查都正常不代表调度链路真的通只有实际提交一个任务并且看到success状态才能说明整个启动流程彻底走通了。6.2 下一步写真实工作流接上Hive和SparkAzkaban启动成功后就具备跑真实任务的能力了。实际工作中最常用的Job类型有command、hive、spark、mapreduce以及用于串联依赖关系的flow。举个例子一个典型的日调度工作流# cleanup_old_data.job typecommand commandsh /data/scripts/cleanup.sh# run_hive_etl.job typehive hive.script/data/scripts/etl.sql dependenciescleanup_old_data# run_spark_report.job typecommand command/opt/spark/bin/spark-submit --class com.example.Report /data/jars/report.jar dependenciesrun_hive_etl用zip打包这三个.job文件上传到Azkaban界面上能看到清晰的依赖图设置好调度时间整个离线数据处理链路就跑起来了。这也是我把启动流程写这么细的原因——很多人在启动环节卡住后面这些真正有价值的工作流设计根本开展不下去。6.3 用Docker部署Azkaban的替代方案如果你用的是Docker方式的Hadoop环境也可以直接用现成的Docker镜像安装Azkaban。Azkaban官方有Docker目录包含构建脚本也有社区维护的镜像。这种方式的好处是环境隔离、快速迁移MySQL和两个Server各跑一个容器用docker-compose统一管理对学习和本地实验特别友好。但需要注意一点容器里跑Azkaban时executor注册到数据库的host默认是容器ID或内网IP要让Web访问到需要在Docker启动参数里指定--networkhost模式或者在配置里显式指定宿主机IP。这个细节很容易导致容器都起来了但任务卡在preparing状态。建议先用本文的纯手工方式把启动逻辑彻底弄懂再用容器方式偷懒效果更好。我在实际使用中还有一个体会无论你用哪种部署方式Azkaban的启动环节本质上就是数据库连通性、SSL配置、双节点注册激活这三件事。把这三件事的底层逻辑摸清了后面无论版本怎么升级、环境怎么迁移你都能很快定位问题所在。这篇博客的宗旨也是把这个“骨架”讲透细节上你可以根据自己机器的实际情况灵活调整。
返回列表