Ambari(五)----Ambari集成Azkaban(亲测有效)

Ambari自定义服务集成–Azkaban

参考资料

Ambari集成组件官方文档:Stacks and Services

Ambari自定义服务集成原理介绍

Ambari—集成Azkaban

文档目录

一. 准备工作

二. Ambari集成Azkaban原理及配置

三. 根据界面提示安装启动Azkaban

四. Ambari集成Azkaban过程中遇到的问题

一. 准备工作

1.1 安装Ambari

Ambari源码编译安装可参考我之前写的博客:

Ambari2.6.0源码编译安装及遇到的问题解决(超详细文档)

Ambari离线安装也可以参考我之前写的博客:

Ambari安装遇到的问题及解决方案

1.2 源码编译配置Azkaban

1.2.1 Azkaban源码编译

下载解压压缩包:

# 下载指定版本的压缩包
wget https://github.com/azkaban/azkaban/archive/3.90.0.tar.gz

# 解压
tar -zxvf 3.90.0.tar.gz

源码编译:

 # 进入到azkaban解压后的根目录,后续该目录用$AZKABAN_HOME替代,使用gradlew方式编译
./gradlew build -x test

如下图所示,编译成功:

在这里插入图片描述

$AZKABAN_HOME/azkaban-?/build/distributions/ 目录下会生成相应的压缩包

源码配置

  1. 创建目录
mkdir -p var/www/html/azkaban
  1. 解压azkaban-db/build/distributions/azkaban-db-0.1.0-SNAPSHOT.tar.gz得到文件create-all-sql-0.1.0-SNAPSHOT.sql

  2. 将以下两个文件放入到var/www/html/azkaban目录下

    a. $AZKABAN_HOME/azkaban-web-server/build/distributions目录下的azkaban-web-server-0.1.0-SNAPSHOT.tar.gz文件

    b. $AZKABAN_HOME/azkaban-exec-server/build/distributions目录下的azkaban-exec-server-0.1.0-SNAPSHOT.tar.gz文件

以上文件可以通过web ui的方式访问,如下图

在这里插入图片描述

1.2.2 Azkaban数据库配置(mysql)

创建azkaban数据库

 create database azkaban character set utf8;

创建azkaban用户

create user 'azkaban'@'%' identified by 'yourpassword';

授予权限

grant all privileges on azkaban.* to azkaban;
flush privileges;

导入azkaban使用的表

# 使用创建的azkaban用户登录mysql
mysql -uazkaban -pyourpassword;
use azkaban;
# 导入azkaban使用的表,该命令需要在该sql脚本所在路径下执行
source create-all-sql-0.1.0-SNAPSHOT.sql
show tables;

在这里插入图片描述

二. Ambari集成Azkaban原理及配置

2.1 Ambari自定义服务集成原理

对于未受 ambari 界面管理的服务,比如 Elasticsearch、Kylin、甚至是一个 jar 包,都可以利用 自定义服务集成相关技术 将 服务 集成到 ambari 界面里。

这样,就可以通过 ambari 实现对 自定义服务 的 安装、配置、启动、监听启动状态、停止、指标监控、告警、快速链接 等很多操作,极其方便。

自定义服务集成,是通过stack来进行,stack的版本目录在 /ambari-server/src/main/resources/stacks下

当我们初始化了ambari-server之后,stack的定义也可以在/var/lib/ambari-server/resources/stacks目录下找到

stacks目录如下图,自定义服务集成的时候,按照如下目录树配置即可:

|_ stacks
   |_ <stack_name>
      |_ <stack_version>
         metainfo.xml
         |_ hooks
         |_ repos
            repoinfo.xml
         |_ services
            |_ <service_name>
               metainfo.xml
               metrics.json
               |_ configuration
                  {configuration files}
               |_ package
                  {files, scripts, templates}

2.2 Ambari集成Azkaban配置

首先在
/var/lib/ambari-server/resources/stacks/HDP/2.6/services下新建目录AZKABAN

2.2.1 metainfo.xml文件配置

进入目录Azkaban,创建metainfo.xml文件,文件内容如下:

<?xml version="1.0"?>
<!--
     # -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-->
<metainfo>
    <schemaVersion>2.0</schemaVersion>
    <services>
        <service>
            <name>AZKABAN</name>
            <displayName>Azkaban</displayName>
            <comment>Azkaban是用于运行Hadoop job的批处理工作流作业调度程序,Azkaban致力于通过作业依赖性进行排序,并提供易于使用的web用户界面来维护和跟踪工作流程.
            </comment>
            <version>3.90.0</version>
            <quickLinksConfigurations>
                <quickLinksConfiguration>
                    <fileName>quicklinks.json</fileName>
                    <default>true</default>
                </quickLinksConfiguration>
            </quickLinksConfigurations>
            <components>
                <component>
                    <name>AZKABAN_WEB</name>
                    <displayName>Azkaban Web Server</displayName>
                    <category>MASTER</category>
                    <cardinality>1</cardinality>
                    <versionAdvertised>true</versionAdvertised>
                    <recovery_enabled>true</recovery_enabled>
                    <commandScript>
                        <script>scripts/azkaban_web.py</script>
                        <scriptType>PYTHON</scriptType>
                        <timeout>300</timeout>
                    </commandScript>
                </component>

                <component>
                    <name>AZKABAN_EXECUTOR</name>
                    <displayName>Azkaban Executor Server</displayName>
                    <category>SLAVE</category>
                    <cardinality>0+</cardinality>
                    <versionAdvertised>true</versionAdvertised>
                    <recovery_enabled>true</recovery_enabled>
                    <commandScript>
                        <script>scripts/azkaban_executor.py</script>
                        <scriptType>PYTHON</scriptType>
                    </commandScript>
                </component>

            </components>

            <configuration-dependencies>
                <config-type>azkaban-common</config-type>
                <config-type>azkaban-executor.properties</config-type>
                <config-type>azkaban-users</config-type>
                <config-type>azkaban-web.properties</config-type>
                <config-type>global.properties</config-type>
                <config-type>log4j.properties</config-type>
            </configuration-dependencies>

        </service>
    </services>
</metainfo>

2.2.2 configuration目录配置
2.2.2.1 azkaban-users.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
     /**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>
    <property>
        <name>content</name>
        <display-name>azkaban-users.xml template</display-name>
        <description>Custom azkaban-users.xml</description>
        <value>
            <![CDATA[
<azkaban-users>
  <user groups="azkaban" password="azkaban" roles="admin" username="azkaban"/>
  <user password="metrics" roles="metrics" username="metrics"/>
  <role name="admin" permissions="ADMIN"/>
  <role name="metrics" permissions="METRICS"/>
</azkaban-users>
            ]]>
        </value>
        <value-attributes>
            <type>content</type>
            <show-property-name>false</show-property-name>
        </value-attributes>
        <on-ambari-upgrade add="true"/>
    </property>

</configuration>

2.2.2.2 global.properties.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>

    <property>
        <name>content</name>
        <display-name>azkaban-users.xml template</display-name>
        <description>Custom azkaban-users.xml</description>
        <value>
            <![CDATA[
retries=10
retry.backoff=10000
failure.emails=
            ]]>
        </value>
        <value-attributes>
            <type>content</type>
            <show-property-name>false</show-property-name>
        </value-attributes>
        <on-ambari-upgrade add="true"/>
    </property>

</configuration>

2.2.2.3 azkaban-executor.properties.xml文件配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
     /**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>
    <property>
        <name>executor.port</name>
        <value>12321</value>
    </property>
    <property>
        <name>azkaban.jobtype.plugin.dir</name>
        <value>plugins/jobtypes</value>
    </property>
    <property>
        <name>executor.maxThreads</name>
        <value>100</value>
    </property>
    <property>
        <name>executor.flow.threads</name>
        <value>100</value>
    </property>
    <property require-input="true">
        <name>azkaban.webserver.url</name>
        <value>http://localhost:10100</value>
        <description>
            example: http://localhost:10100
        </description>
    </property>
</configuration>


2.2.2.4 azkaban-web.properties.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>

    <property>
        <name>mail.sender</name>
        <value>xxx@163.com</value>
    </property>
    <property>
        <name>mail.host</name>
        <value>smtp.163.com</value>
    </property>
    <property>
        <name>mail.user</name>
        <value>xxx@163.com</value>
    </property>
    <property>
        <name>mail.password</name>
        <value>xxx</value>
    </property>


    <property>
        <name>azkaban.use.multiple.executors</name>
        <value>true</value>
    </property>
    <property>
        <name>azkaban.executorselector.filters</name>
        <value>StaticRemainingFlowSize,MinimumFreeMemory,CpuStatus</value>
    </property>
    <property>
        <name>azkaban.executorselector.comparator.NumberOfAssignedFlowComparator</name>
        <value>1</value>
    </property>
    <property>
        <name>azkaban.executorselector.comparator.Memory</name>
        <value>1</value>
    </property>
    <property>
        <name>azkaban.executorselector.comparator.LastDispatched</name>
        <value>1</value>
    </property>
    <property>
        <name>azkaban.executorselector.comparator.CpuUsage</name>
        <value>1</value>
    </property>

</configuration>


2.2.2.5 log4j.properties.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>
    <property>
        <name>content</name>
        <display-name>log4j.properties template</display-name>
        <description>Custom log4j.properties</description>
        <value>
            log4j.rootLogger=INFO, Console
            log4j.logger.azkaban=INFO, server
            log4j.appender.server=org.apache.log4j.RollingFileAppender
            log4j.appender.server.layout=org.apache.log4j.PatternLayout
            log4j.appender.server.File=logs/azkaban.log
            log4j.appender.server.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss.SSS Z} %5p [%c{1}] [%t] [Azkaban] %m%n
            log4j.appender.server.MaxFileSize=1024MB
            log4j.appender.server.MaxBackupIndex=2
            log4j.appender.Console=org.apache.log4j.ConsoleAppender
            log4j.appender.Console.layout=org.apache.log4j.PatternLayout
            log4j.appender.Console.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss.SSS Z} %5p [%c{1}] [%t] [Azkaban]
            %m%n
        </value>
        <value-attributes>
            <type>content</type>
            <show-property-name>false</show-property-name>
        </value-attributes>
        <on-ambari-upgrade add="true"/>
    </property>

</configuration>

2.2.2.6 azkaban-common.xml配置
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
     /**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>
    <property>
        <name>azkaban.name</name>
        <value>Prod</value>
    </property>
    <property>
        <name>azkaban.label</name>
        <value>Prod Azkaban</value>
    </property>
    <property>
        <name>azkaban.color</name>
        <value>#FF3601</value>
    </property>
    <property>
        <name>azkaban.default.servlet.path</name>
        <value>/index</value>
    </property>
    <property>
        <name>web.resource.dir</name>
        <value>web/</value>
    </property>
    <property>
        <name>default.timezone.id</name>
        <value>Asia/Shanghai</value>
    </property>

    <property>
        <name>user.manager.class</name>
        <value>azkaban.user.XmlUserManager</value>
    </property>
    <property>
        <name>user.manager.xml.file</name>
        <value>conf/azkaban-users.xml</value>
    </property>

    <property>
        <name>executor.global.properties</name>
        <value>conf/global.properties</value>
    </property>
    <property>
        <name>azkaban.project.dir</name>
        <value>projects</value>
    </property>

    <property>
        <name>velocity.dev.mode</name>
        <value>false</value>
    </property>

    <property>
        <name>jetty.use.ssl</name>
        <value>false</value>
    </property>
    <property>
        <name>jetty.maxThreads</name>
        <value>100</value>
    </property>
    <property>
        <name>jetty.port</name>
        <value>10200</value>
    </property>

    <property>
        <name>lockdown.create.projects</name>
        <value>false</value>
    </property>
    <property>
        <name>cache.directory</name>
        <value>cache</value>
    </property>

    <property>
        <name>jetty.connector.stats</name>
        <value>true</value>
    </property>
    <property>
        <name>executor.connector.stats</name>
        <value>true</value>
    </property>

    <property>
        <name>database.type</name>
        <value>mysql</value>
    </property>
    <property require-input="true">
        <name>mysql.host</name>
        <value></value>
    </property>
    <property require-input="true">
        <name>mysql.port</name>
        <value>3306</value>
    </property>
    <property require-input="true">
        <name>mysql.database</name>
        <value>azkaban</value>
    </property>
    <property require-input="true">
        <name>mysql.user</name>
        <value>azkaban</value>
    </property>
    <property require-input="true">
        <name>mysql.password</name>
        <value></value>
    </property>
    <property>
        <name>mysql.numconnections</name>
        <value>200</value>
    </property>

</configuration>

2.2.3 package/scripts配置
2.2.3.1 azkaban_executor.py配置
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os.path as path
import time

from common import azkabanHome, azkabanExecTarUrl, azkabanExecTarName, azkabanConfPath
from resource_management.core.exceptions import ExecutionFailed, ComponentIsNotRunning
from resource_management.core.resources.system import Execute
from resource_management.libraries.script.script import Script


class ExecutorServer(Script):
    def install(self, env):
        Execute('yum install -y python-requests')

        tmpAzkabanExecTarPath = '/tmp/' + azkabanExecTarName
        Execute('mkdir -p {0}'.format(azkabanHome))
        Execute('wget --no-check-certificate {0} -O {1}'.format(azkabanExecTarUrl, tmpAzkabanExecTarPath))
        Execute('tar -xf {0} -C {1} --strip-components=1'.format(tmpAzkabanExecTarPath, azkabanHome))

        Execute(
            'cd {0} && '
            'chmod +x bin/start-exec.sh && '
            'chmod +x bin/shutdown-exec.sh && '
            'chmod +s bin/internal/internal-start-executor.sh'.format(azkabanHome)
        )

        self.configure(env)

    def stop(self, env):
        Execute('cd {0} && ./bin/shutdown-exec.sh'.format(azkabanHome))

    def start(self, env):
        self.configure(env)
        Execute('cd {0} && ./bin/start-exec.sh'.format(azkabanHome))
        from params import azkaban_executor_properties
        executor_port = int(azkaban_executor_properties['executor.port'])
        url = 'http://127.0.0.1:{0}/executor?action=ping'.format(executor_port)
        maxRetryCount = 10
        retryCount = 0
        import requests
        while True:
            try:
                resp = requests.get(url)
                print(resp.text)
                if json.loads(resp.text)['status'] == 'alive':
                    print('executor is alive')
                    Execute('curl -G "localhost:{0}/executor?action=activate" && echo'.format(executor_port))
                    print('after activate')
                    break
            except:
                print('executor is not alive')
            time.sleep(1)
            retryCount += 1
            if retryCount > maxRetryCount:
                raise Exception('web start failed')

    def status(self, env):
        # TODO 可优化,和start逻辑一致
        try:
            Execute(
                'export AZ_CNT=`ps -ef |grep -v grep |grep azkaban-exec-server | wc -l` && `if [ $AZ_CNT -ne 0 ];then exit 0;else exit 3;fi `'
            )
        except ExecutionFailed as ef:
            if ef.code == 3:
                raise ComponentIsNotRunning("ComponentIsNotRunning")
            else:
                raise ef

    def configure(self, env):
        from params import azkaban_executor_properties, log4j_properties, azkaban_common, global_properties
        key_val_template = '{0}={1}\n'

        with open(path.join(azkabanConfPath, 'azkaban.properties'), 'w') as f:
            for key, value in azkaban_common.iteritems():
                f.write(key_val_template.format(key, value))
            for key, value in azkaban_executor_properties.iteritems():
                if key != 'content':
                    f.write(key_val_template.format(key, value))
            if azkaban_executor_properties.has_key('content'):
                f.write(str(azkaban_executor_properties['content']))

        with open(path.join(azkabanConfPath, 'log4j.properties'), 'w') as f:
            if log4j_properties.has_key('content'):
                f.write(str(log4j_properties['content']))

        with open(path.join(azkabanConfPath, 'global.properties'), 'w') as f:
            if global_properties.has_key('content'):
                f.write(str(global_properties['content']))


if __name__ == '__main__':
    ExecutorServer().execute()


2.2.3.2 azkaban_web.py配置
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os.path as path
import time

from common import azkabanHome, azkabanWebTarUrl, azkabanWebTarName, \
    azkabanConfPath
from resource_management.core.exceptions import ExecutionFailed, ComponentIsNotRunning
from resource_management.core.resources.system import Execute
from resource_management.libraries.script.script import Script


class WebServer(Script):
    def install(self, env):
        Execute('yum install -y python-requests')

        tmpAzkabanWebTarPath = '/tmp/' + azkabanWebTarName
        Execute('mkdir -p {0}'.format(azkabanHome))
        Execute('wget --no-check-certificate {0} -O {1}'.format(azkabanWebTarUrl, tmpAzkabanWebTarPath))
        Execute('tar -xf {0} -C {1} --strip-components=1'.format(tmpAzkabanWebTarPath, azkabanHome))

        Execute(
            'cd {0} && '
            'chmod +x bin/start-web.sh && '
            'chmod +x bin/shutdown-web.sh && '
            'chmod +s bin/internal/internal-start-web.sh'.format(azkabanHome)
        )

        self.configure(env)

    def stop(self, env):
        Execute('cd {0} && ./bin/shutdown-web.sh'.format(azkabanHome))

    def start(self, env):
        self.configure(env)

        maxRetryCount = 10
        retryCount = 0

        from params import host_info, azkaban_executor_properties
        executor_port = int(azkaban_executor_properties['executor.port'])
        execHosts = host_info['azkaban_executor_hosts']
        urlTmpl = 'http://{0}:{1}/executor?action=getStatus'
        import requests
        while True:
            for execHost in execHosts:
                try:
                    url = urlTmpl.format(execHost, executor_port)
                    print(url)
                    resp = requests.get(url)
                    print(resp.text)
                    if json.loads(resp.text)['isActive'] == 'true':
                        Execute('cd {0} && ./bin/start-web.sh'.format(azkabanHome))
                        return
                except:
                    print('web is not alive')
                time.sleep(0.5)
            time.sleep(1)
            retryCount += 1
            if retryCount > maxRetryCount:
                raise Exception('web start failed')

    def status(self, env):
        try:
            Execute(
                'export AZ_CNT=`ps -ef |grep -v grep |grep azkaban-web-server | wc -l` && `if [ $AZ_CNT -ne 0 ];then exit 0;else exit 3;fi `'
            )
        except ExecutionFailed as ef:
            if ef.code == 3:
                raise ComponentIsNotRunning("ComponentIsNotRunning")
            else:
                raise ef

    def configure(self, env):
        from params import azkaban_common, azkaban_web_properties, azkaban_users, global_properties, log4j_properties
        key_val_template = '{0}={1}\n'

        with open(path.join(azkabanConfPath, 'azkaban.properties'), 'w') as f:
            for key, value in azkaban_common.iteritems():
                f.write(key_val_template.format(key, value))
            for key, value in azkaban_web_properties.iteritems():
                if key != 'content':
                    f.write(key_val_template.format(key, value))
            if azkaban_web_properties.has_key('content'):
                f.write(str(azkaban_web_properties['content']))

        with open(path.join(azkabanConfPath, 'azkaban-users.xml'), 'w') as f:
            if azkaban_users.has_key('content'):
                f.write(str(azkaban_users['content']))

        with open(path.join(azkabanConfPath, 'global.properties'), 'w') as f:
            if global_properties.has_key('content'):
                f.write(str(global_properties['content']))

        with open(path.join(azkabanConfPath, 'log4j.properties'), 'w') as f:
            if log4j_properties.has_key('content'):
                f.write(str(log4j_properties['content']))


if __name__ == '__main__':
    WebServer().execute()

2.2.3.3 common.py配置
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os

import ConfigParser

script_dir = os.path.dirname(os.path.realpath(__file__))
config = ConfigParser.ConfigParser()
config.readfp(open(os.path.join(script_dir, 'download.ini')))

azkabanHome = '/data/azkaban'
azkabanConfPath = azkabanHome + '/conf'

azkabanWebTarUrl = config.get('download', 'azkaban_web_tar_url')
azkabanExecTarUrl = config.get('download', 'azkaban_executor_tar_url')

azkabanWebTarName = azkabanWebTarUrl.split('/')[-1]
azkabanExecTarName = azkabanExecTarUrl.split('/')[-1]

2.2.3.4 params.py配置
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from resource_management.libraries.script.script import Script

# config object that holds the configurations declared in the config xml file
config = Script.get_config()

azkaban_web_properties = config['configurations']['azkaban-web.properties']
azkaban_executor_properties = config['configurations']['azkaban-executor.properties']
azkaban_users = config['configurations']['azkaban-users']
azkaban_common = config['configurations']['azkaban-common']
global_properties = config['configurations']['global.properties']
log4j_properties = config['configurations']['log4j.properties']

host_info = config['clusterHostInfo']
host_level_params = config['hostLevelParams']
java_home = host_level_params['java_home']

2.2.3.5 download.ini配置
# 这里配置的为1.2.1过程中放入/var/www/html/azkaban目录下的两个文件
[download]
azkaban_web_tar_url = http://ip/azkaban/azkaban-web-server-0.1.0-SNAPSHOT.tar.gz
azkaban_executor_tar_url = http://ip/azkaban/azkaban-exec-server-0.1.0-SNAPSHOT.tar.gz

2.2.4 quicklinks.json文件配置
{
  "name": "default",
  "description": "default quick links configuration",
  "configuration": {
    "protocol": {
      "type": "HTTP_ONLY"
    },
    "links": [
      {
        "name": "azkaban_web",
        "label": "Azkaban Web",
        "component_name": "AZKABAN_WEB",
        "requires_user_name": "false",
        "url": "%@://%@:%@:10200",
        "port": {
          "http_property": "jetty.port",
          "regex": "^(\\d+)$",
          "site": "azkaban-web.properties"
        }
      }
    ]
  }
}


2.3 重启ambari-server

ambari-server restart

登录ambari后,已经可以在add service界面查找到Azkaban服务

在这里插入图片描述

三. 根据界面提示安装启动Azkaban

根据界面提示逐步操作,即可初始化Azkaban
此时,遇到错误按照日志提示逐步排查即可:

如下图所示,Azkaban安装启动成功!

在这里插入图片描述

根据 2.2.2.3 azkaban-executor.properties.xml配置项azkaban.webserver.url配置的value值访问web界面

根据 2.2.2.1 azkaban-users.xml配置的账户名和密码登录azkaban

如下图所示,配置完成!
在这里插入图片描述

四. Ambari集成Azkaban过程中遇到的问题

4.1 azkaban源码clean操作报错

./gradlew clean Exception in thread "main"
java.lang.RuntimeException: Timeout of 120000 reached waiting for exclusive access to file:
/root/.gradle/wrapper/dists/gradle-4.1-all/bzyivzo6n839fup2jbap0tjew/gradle-4.1-all.zip at
org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65) at
org.gradle.wrapper.Install.createDist(Install.java:48) at
org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61) 

解决办法:

  1. 删除报错指向的文件夹
/root/.gradle/wrapper/dists/gradle-4.1-all
  1. 重新执行命令
    在这里插入图片描述

问题解决:

4.2 azkaban安装初始化报错:

File "/var/lib/ambari-agent/cache/stacks/HDP/2.6/services/AZKABAN/package/scripts/azkaban_web.py", line 67
    self.configure(env)
       ^
IndentationError: expected an indented block

类似的问题大多数是python脚本缩进问题导致的,python对缩进的要求十分严格,按照报错提示修改对应位置的脚本即可

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值