我觉得之所以要设计成这样是为了将每个flow独立出来,方便flow的重用。
4、用户管理
azkaban中有用户和用户组的概念,用户和用户组以及权限的配置信息保存在配置文件azkaban-users.xml中,认证的方式是由azkaban.user.XmlUserManager来实现的,具体的配置可以在azkaban.properties(web服务器的conf下)进行配置:
Parameter |
Default |
user.manager.class |
azkaban.user.XmlUserManager |
user.manager.xml.file |
azkaban-users.xml |
我们在azkaban-users.xml可以配置三类内容:user、group和role,user项可以配置username、password、roles、group信息,分别配置用户名、密码、用户的权限以及所属的组;group项可以配置name和roles,分别用于配置组名和这个组使用的权限;role定义了权限信息,可以配置name和permissions,分别表示规则名和赋予的权限信息。azkaban支持的权限包括:
Permissions |
Values |
ADMIN |
可以做任务事情,包括给其他用户添加、修改权限 |
READ |
只能访问每一个project的内容和日志信息 |
WRITE |
可以在已创建的project上传、修改任务的属性,可以删除任何的project |
EXECUTE |
允许用户执行任何的任务流 |
SCHEDULE |
允许用户添加、删除任何任务流的调度信息 |
CREATEPROJECTS |
在禁止创建project的情况下仍允许创建新的project |
这里的权限设置没有细化到每一个user在每一个project中,每一个用户所拥有的权限可以在每一个project下面执行相同的操作,另外用户和用户组之间的权限信息还不是很明确,如果使用用户组作为权限的分配单位(即一个用户组下的所有用户拥有相同的权限),每个用户再次指定权限就有点多余了。
5、API
azkaban也提供了API接口来使用,这样可以基于azkaban实现自己的管理方式,这些接口是通过HTTPS的方式与web服务器进行通信的,因为在azkaban中有用户和权限的概念,所以在调用API之前需要登录,登录成功之后会返回用户一个session id,之后所有的操作都需要携带这个id以判断用户是否有权限。如果session id无效,那么调用API会返回"error"
: "session"的信息,如果不携带session.id参数,会返回登陆界面的html文件内容(有些session id的访问也会返回这样的内容)。azkaban提供的API包括:具体请参照官方文档:
http://azkaban.github.io/azkaban/docs/2.5/#ajax-api
1、Authenticate:用户登录操作,需要携带用户名和密码,如果成功登录则返回一个session id用于之后的请求。
2、Create a Project:创建一个新的project,这需要在任何关于这个project操作之前进行,需要输入project的name作为这个project的唯一标示,还需要包含这个project的描述信息,其实和在web页面上创建project的输入一样。
3、Delete a Project:删除一个已经存在的project,该请求没有回复信息,需要输入project的标识。
4、Upload a Project Zip:上传一个zip文件到一个project,一般在创建一个project完成之后,之后的上传将覆盖以前上传的内容。
5、Fetch Flows of a Project:获取一个project下的所有flow信息,输入需要指定project的标识,一个project下面可能存在多个flow,输出的flow只包含flowId标识每一个flow。
6、Fetch Jobs of a Flow:获取一个flow下所有job的信息,因为在API端每个命令都是独立的,所以这里需要输入project的标识和flow的标识,输出包含每一个job的信息,包括job的标识(id)、job类型以及这个job直接以来的job。
7、Fetch Executions of a Flow:获取flow的执行情况,需要制定特定的project和flow,这个接口可以分页返回,所以需要制定start指定开始的index和length指定返回的个数,因为每一个flow都可以单独的或者作为其他flow的子flow执行,这里返回该flow指定区间内的每一次执行的信息。每一个执行信息包括起始时间、提交执行的用户、执行的状态、提交时间、这次执行在全局的id(递增的execid),projectid、结束时间和flowId。
8、Fetch Running Executions of a Flow:获取当前正在执行的flow的执行信息,输入包括project和flow的标识,返回的是该flow正在执行的所有执行id(全局的exec id)。
9、Execute a Flow:启动一个flow的执行,这个输入比较多,因为在web界面上每次启动flow的执行都需要设置几项配置,可以在该接口设置出了调度之外的乞讨配置信息,输入还需要包括project和flow的标识,输出为这个flow的id和本次执行的exec id
10、Cancel a Flow Execution:取消一次flow的执行,需要输入的是全局的exec id,因为这个id是全局唯一的,那么可以通过它来进行标识,不需要再输入project和flow的标识了,如果这个执行已经结束,会返回错误信息。
11、Pause a Flow Execution:暂停一次执行,输入为exec id。如果这个执行不是处于running状态,会返回错误信息。
12、Resume a Flow Execution:重新启动一次执行,输入为exec id,如果这次执行已经在进行,不返回任何错误,如果它不再运行则返回错误信息。
13、Fetch a Flow Execution:获取一次执行的所有信息,输入为exec id,输出包括这次执行的属性(参见7),还包括这次执行的所有的job的执行情况。
14、Fetch Execution Job Logs:获取一次执行中的一个job的执行日志,可以将job的执行日志作为一个文件,这里需要制定exec id、job的标识以及读取这个文件内容的返回(offset+length),返回的为指定范围的日志内容。
15、Fetch Flow Execution Updates:这个是返回上次查看之后每个任务的执行情况?这个有点疑惑。应该是在flow执行的时候执行进度的信息获取。
从这里的接口可以看出,azkaban提供的API只能用于简单创建project、flow,查看project、flow、execute等操作,而web界面的操作要比这丰富得多,如果我们希望基于azkaban进行开发的话,在这些接口的基础上,我觉得还可以对azkaban的数据库进行分析,从数据库中得到我们想要的信息(基本的写操作都能够通过这些API实现,所以我们只需要从数据库中读取)。但是这样相对于使用API还是有个弊端,毕竟随着版本的更新数据库的结构可能会发生变化,但是这也不失为一种方式。
6、总结
好了,本文主要介绍了azkaban的安装以及使用情况,但是它主要还是用来执行hadoop生态圈里面的各种操作以及java程序的,但是简单的使用还是让我认识到这个工具的强大,但是我还是有一个疑问,azkaban的三个模块的主要功能分别是:mysql用于数据的存储,web服务器用来更方面的使用和图形化展示,executor才是真正的执行任务的服务器,所以所有job的执行都需要在executor所在的机器上进行,job的执行时启动一个子进程的方式(可以通过在job执行是查看正在执行的job命令判断),那么这个executor需要安装所有的支持的任务的工具、jar包等。如果是对于那种占用资源比较多的job(例如一个java程序CPU使用率达到100%),那么就会对其他的job的执行有影响,所以这种架构的可扩展性是否有点欠缺?或者是由于这个工具主要是执行一些hadoop任务,客户端的压力并不大,所以没有考虑这方面。
不过总体来说这是一个比较好的工具,至少web界面可以很方便和直观的查看任务的执行以及运行结果(P.S.azkaban对任务执行结是否成功是怎么判断的?),虽然文档上说它可以支持多个executor,但是实际上并没有发现这么用的,我觉得可以继续改进它来实现多个机器之间任意的程序之间的并行,例如有多个job可以并行执行的,我有多台executor服务器,我可以将任何一个job部署到任何一个executor上执行,充分利用所有的硬件资源。我靠,这不就成了hadoop中jobTracker和TaskTracker的结果了?算了。这个就纯属个人的瞎扯了。