azkaban定制

azkaban多用户定制

azkaban调度系统分为webServer和executorServer两部分。执行一个工作流,需要指定该工作流执行的executorServer。在webServer中,可以通过指定Flow Parameters的useExecutor参数来选择executorServer。

对于没有指定该参数的工作流,azkaban提供一个自动选择executor的算法。在自动选择算法中,azkaban并没有给executor分组这一功能。这在平常使用中没有问题,但是我们有这样一套需求,不同team有自己的服务器,服务器上部署有不同的executor-server,我们希望不同team提交时能够在自己的服务器上执行任务(这涉及到工作流的环境依赖问题,比如有些依赖hive,有些依赖其他的类库,但是并不是所有服务器都有这样的类库)。为了实现这一点,我们对azkaban做了定制。

为了实现这一需求,我们的定制主要基于三个方面:

  1. 提交工作流时强制检查useExecutor参数
  2. 基于工作流配置文件自动填写默认useExecutor参数
  3. 参数的序列化/反序列化定制

为了强制用户使用useExecutor参数,我们做了两方面的修改。首先,在工作流提交时点击蓝色的execute其实是调用了一个ajax接口。该接口的实现是azkaban.webapp.servlet.ExecutorServlet的ajaxExecuteFlow函数。在该函数中我们强制检查url参数是否含有useExecutor,如果没有则返回HTTP ERROR 500,使得该工作流无法提交。同时,我们禁用了azkaban的executorServer自动选择机制,(azkaban.executor.ExecutorManager的selectExecutor函数中禁用了自动选择),来确保工作流不被调度到其他executor server上。

为了简化用户的操作,我们在工作流的配置文件顶层增加了一个文件userExecutor.properties。该文件中配置的userExecutor属性为该工作流中的默认executor,在执行时会被自动填写在flow parameters中。该实现我们参考了azkaban中关于指定failure.email的实现方式。在project页面点击execute Flow(绿色按钮)时,他会调用fetchFlowInfo的ajax(azkaban.webapp.servlet。ExecutorServlet的ajaxFetchFlowInfo函数),我们在配置文件中添加的属性可以在flow的props中读到。因此,在ajaxFetchFlowInfo中添加以下代码即可将useExecutor传入webServer。

1
2
3
4
5
6
7
8
9
HashMap<String, Object> flowParams = new HashMap<String, Object>();
FlowProps flowProps = flow.getFlowProps("useExecutor.properties");
if (flowProps != null) {
Props props = flowProps.getProps();
if (props != null && props.containsKey("useExecutor")) {
flowParams.put("useExecutor", props.getString("useExecutor"));
}
}
ret.put("flowParam", flowParams);

在webServer中,由ajax.js将参数填入弹出框,由于我们已经将useExecutor传入了flowParams域,前端不需要经过任何修改即可得到传入的参数。

最后需要修改的是flow的序列化和反序列化操作。第一次将工作流配置文件传入azkaban中时,azkaban会将配置信息序列化为一个json传入数据库中,当webserver重启时会读取所有的工作流信息并反序列化。这里azkaban的序列化有一个问题就是他不会储存flow的props信息。这导致我们重启webserver以后无法得到之前配置的useExecutor参数。通过重新编写azkaban.flow.FlowProps中的toObjedct()和fromObject()参数将props写入object,我们就可以持久化这些信息。

通过这样的定制,我们基本实现了多用户多team共用一套azkaban的目标。在实现过程中我们同样考虑过一下两个实现方案。

  1. 在生成webserver账户时配置其可以调用的executor。在工作流自动选择阶段值选择账户有权限调用的executor

    • 这一方案的缺陷在于webserver账户是通过一个xml管理的。管理代码在webserver包中,但是工作流自动选择代码在common包。webserver包本身依赖common包,使得common拿到webserver的User类比较困难。
  2. 在executor中制定可以调用他的user。

    • 这一方案比上一方案好的优点在于executor的信息在数据库中,更容易被common包得到。但是该方案设计修改数据库结构,比较复杂。同时每次添加用户都需要更新所有的executor的用户列表,易用性较差。

同时注意到,方案二是强制限制用户使用executor的权限,而我们实现的方案是通过预设参数的方式引导用户,用户可以修改该参数,并且我们对修改参数不做限制。这也是实现的权限级别上的不同。


本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证,欢迎转载,但转载请注明来自http://thousandhu.github.io,并保持转载后文章内容的完整。本人保留所有版权相关权利。

本文链接:http://thousandhu.github.io/2016/01/07/azkaban定制/