在 HDInsight 中将 Oozie 与 Hadoop 配合使用以定义和运行工作流

Note

本文涉及的 SDK 和工具是在 Microsoft Corporation 运行的 Azure 服务中使用的,而在中国, Azure 是由 21Vianet 运行的。 请根据需要参阅中国区 Azure 应用程序开发说明

了解如何使用 Apache Oozie 定义工作流以及如何在 HDInsight 上运行工作流。 要了解 Oozie 协调器,请参阅将基于时间的 Hadoop Oozie 协调器与 HDInsight 配合使用

Apache Oozie 是一个管理 Hadoop 作业的工作流/协调系统。 它与 Hadoop 堆栈集成,支持 Apache MapReduce、Apache Pig、Apache Hive 和 Apache Sqoop 的 Hadoop 作业。 它也能用于安排特定于某系统的作业,例如 Java 程序或 shell 脚本。

你根据本教程中的说明实现的工作流包含两个操作:

工作流关系图

  1. Hive 操作运行 HiveQL 脚本,统计 log4j 文件中每个日志级类型的出现次数。 每个 log4j 文件都包含一行字段,其中包含用于显示类型和严重性的 [LOG LEVEL] 字段,例如:

     2012-02-03 18:35:34 SampleClass6 [INFO] everything normal for id 577725851
     2012-02-03 18:35:34 SampleClass4 [FATAL] system problem at id 1991281254
     2012-02-03 18:35:34 SampleClass3 [DEBUG] detail for id 1304807656
     ...
    

    Hive 脚本的输出结果类似如下:

     [DEBUG] 434
     [ERROR] 3
     [FATAL] 1
     [INFO]  96
     [TRACE] 816
     [WARN]  4
    

    有关 Hive 的详细信息,请参阅将 Hive 与 HDInsight 配合使用

  2. Sqoop 操作将 HiveQL 输出结果导出到 Azure SQL 数据库中的表。 有关 Sqoop 的详细信息,请参阅将 Hadoop Sqoop 与 HDInsight 配合使用

Note

有关在 HDInsight 群集上支持的 Oozie 版本,请参阅 HDInsight 提供的 Hadoop 群集版本有哪些新增功能?

先决条件

开始学习本教程之前,必须具备以下项:

  • 配备 Azure PowerShell 的工作站

Important

使用 Azure Service Manager 管理 HDInsight 资源的 Azure PowerShell 支持已弃用,已在 2017 年 1 月 1 日删除。 本文档中的步骤使用的是与 Azure Resource Manager 兼容的新 HDInsight cmdlet。

请按照 Install and configure Azure PowerShell (安装和配置 Azure PowerShell)中的步骤安装最新版本的 Azure PowerShell。 如果你的脚本需要修改后才能使用与 Azure Resource Manager 兼容的新 cmdlet,请参阅 迁移到适用于 HDInsight 群集的基于 Azure Resource Manager 的开发工具 ,了解详细信息。

Oozie 工作流定义是用 hPDL(一种 XML 过程定义语言)编写的。 默认的工作流文件名为 workflow.xml。 以下是本教程中使用的工作流文件。

<workflow-app name="useooziewf" xmlns="uri:oozie:workflow:0.2">
    <start to = "RunHiveScript"/>

    <action name="RunHiveScript">
        <hive xmlns="uri:oozie:hive-action:0.2">
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <configuration>
                <property>
                    <name>mapred.job.queue.name</name>
                    <value>${queueName}</value>
                </property>
            </configuration>
            <script>${hiveScript}</script>
            <param>hiveTableName=${hiveTableName}</param>
            <param>hiveDataFolder=${hiveDataFolder}</param>
            <param>hiveOutputFolder=${hiveOutputFolder}</param>
        </hive>
        <ok to="RunSqoopExport"/>
        <error to="fail"/>
    </action>

    <action name="RunSqoopExport">
        <sqoop xmlns="uri:oozie:sqoop-action:0.2">
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <configuration>
                <property>
                    <name>mapred.compress.map.output</name>
                    <value>true</value>
                </property>
            </configuration>
        <arg>export</arg>
        <arg>--connect</arg>
        <arg>${sqlDatabaseConnectionString}</arg>
        <arg>--table</arg>
        <arg>${sqlDatabaseTableName}</arg>
        <arg>--export-dir</arg>
        <arg>${hiveOutputFolder}</arg>
        <arg>-m</arg>
        <arg>1</arg>
        <arg>--input-fields-terminated-by</arg>
        <arg>"\001"</arg>
        </sqoop>
        <ok to="end"/>
        <error to="fail"/>
    </action>

    <kill name="fail">
        <message>Job failed, error message[${wf:errorMessage(wf:lastErrorNode())}] </message>
    </kill>

    <end name="end"/>
</workflow-app>

该工作流中定义了两个操作。 start-to 操作是 RunHiveScript。 如果该操作成功运行,则下一个操作是 RunSqoopExport

RunHiveScript 有几个变量。 在使用 Azure PowerShell 从工作站提交 Oozie 作业时,会传递值。

工作流变量说明
${jobTracker}指定 Hadoop 作业跟踪器的 URL。 在 HDInsight 版本 3.0 和 2.1 中使用 jobtrackerhost:9010
${nameNode}指定 Hadoop 名称节点的 URL。 使用默认的文件系统地址,例如 wasb://&lt;containerName&gt;@<storageAccountName>.blob.core.chinacloudapi.cn
${queueName}指定作业将提交到的队列名称。 使用默认值
Hive 操作变量说明
${hiveDataFolder}指定 Hive Create Table 命令的源目录。
${hiveOutputFolder}指定 INSERT OVERWRITE 语句的输出文件夹。
${hiveTableName}指定引用 log4j 数据文件的 Hive 表的名称。
Sqoop 操作变量说明
${sqlDatabaseConnectionString}指定 Azure SQL 数据库连接字符串。
${sqlDatabaseTableName}指定数据将导出到的 Azure SQL 数据库表。
${hiveOutputFolder}指定 Hive INSERT OVERWRITE 语句的输出文件夹。 这是用于 Sqoop 导出 (export-dir) 的同一个文件夹。

有关 Oozie 工作流和使用工作流操作的详细信息,请参阅 Apache Oozie 4.0 文档(适用于 HDInsight 3.0 版)或 Apache Oozie 3.3.2 文档(适用于 HDInsight 2.1 版)。

工作流中的 Hive 操作调用 HiveQL 脚本文件。 此脚本文件包含三个 HiveQL 语句:

DROP TABLE ${hiveTableName};
CREATE EXTERNAL TABLE ${hiveTableName}(t1 string, t2 string, t3 string, t4 string, t5 string, t6 string, t7 string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE LOCATION '${hiveDataFolder}';
INSERT OVERWRITE DIRECTORY '${hiveOutputFolder}' SELECT t4 AS sev, COUNT(*) AS cnt FROM ${hiveTableName} WHERE t4 LIKE '[%' GROUP BY t4;
  1. DROP TABLE 语句 删除 log4j Hive 表(如果存在)。
  2. CREATE TABLE 语句 创建指向 log4j 日志文件位置的 log4j Hive 外部表。 字段分隔符为“,”。 默认分行符为“\n”。 如果想要多次运行 Oozie 工作流,可使用 Hive 外部表来避免从原始位置删除数据文件。
  3. INSERT OVERWRITE 语句可从 log4j Hive 表中计算每个日志级别类型的出现次数,并将输出保存到 Azure 存储中的 Blob。

该脚本中使用了三个变量:

  • ${hiveTableName}
  • ${hiveDataFolder}
  • ${hiveOutputFolder}

工作流定义文件(本教程中的 workflow.xml)在运行时会将三个值传递到这个 HiveQL 脚本。

工作流文件和 HiveQL 文件同时存储在 Blob 容器中。 本教程后面要使用的 PowerShell 脚本会将这两个文件复制到默认存储帐户。

使用 PowerShell 提交 Oozie 作业

Azure PowerShell 目前不提供任何用于定义 Oozie 作业的 cmdlet。 可以使用 Invoke-RestMethod cmdlet 调用 Oozie Web 服务。 Oozie Web 服务 API 是 HTTP REST JSON API。 有关 Oozie Web 服务 API 的详细信息,请参阅 Apache Oozie 4.0 文档(用于 HDInsight 版本 3.0)或 Apache Oozie 3.3.2 文档(用于 HDInsight 版本 2.1)。

本部分中的 PowerShell 脚本将执行以下步骤:

  1. 连接到 Azure。
  2. 创建 Azure 资源组。 有关详细信息,请参阅将 Azure PowerShell 与 Azure 资源管理器配合使用
  3. 创建一个 Azure SQL 数据库服务器、一个 Azure SQL 数据库和两个表。 工作流中的 Sqoop 操作将使用这些项。

    表的名称为 log4jLogCount

  4. 创建用于运行 Oozie 作业的 HDInsight 群集。

    若要检查群集,可以使用 Azure 门户或 Azure PowerShell。

  5. 将 Oozie 工作流文件和 HiveQL 脚本文件复制到默认文件系统。

    这两个文件将存储在公共 Blob 容器中。

    • 将 HiveQL 脚本 (useoozie.hql) 复制到 Azure 存储 (wasb:///tutorials/useoozie/useoozie.hql)。
    • 将 workflow.xml 复制到 wasb:///tutorials/useoozie/workflow.xml。
    • 将数据文件 (/example/data/sample.log) 复制到 wasb:///tutorials/useoozie/data/sample.log。
  6. 提交 Oozie 作业。

    若要检查 OOzie 作业结果,请使用 Visual Studio 或其他工具连接到 Azure SQL 数据库。

脚本如下。 可以通过 Windows PowerShell ISE 运行该脚本。 只需配置前 7 个变量。

#region - provide the following values

$subscriptionID = "<Enter your Azure subscription ID>"

# SQL Database server login credentials used for creating and connecting
$sqlDatabaseLogin = "<Enter SQL Database Login Name>"
$sqlDatabasePassword = "<Enter SQL Database Login Password>"

# HDInsight cluster HTTP user credential used for creating and connectin
$httpUserName = "admin"  # The default name is "admin"
$httpPassword = "<Enter HDInsight Cluster HTTP User Password>"

# Used for creating Azure service names
$nameToken = "<Enter an Alias>"
$namePrefix = $nameToken.ToLower() + (Get-Date -Format "MMdd")
#endregion

#region - variables

# Resource group variables
$resourceGroupName = $namePrefix + "rg"
$location = "China East" # used by all Azure services defined in this tutorial

# SQL database varialbes
$sqlDatabaseServerName = $namePrefix + "sqldbserver"
$sqlDatabaseName = $namePrefix + "sqldb"
$sqlDatabaseConnectionString = "Data Source=$sqlDatabaseServerName.database.chinacloudapi.cn;Initial Catalog=$sqlDatabaseName;User ID=$sqlDatabaseLogin;Password=$sqlDatabasePassword;Encrypt=true;Trusted_Connection=false;"
$sqlDatabaseMaxSizeGB = 10

# Used for retrieving external IP address and creating firewall rules
$ipAddressRestService = "http://bot.whatismyipaddress.com"
$fireWallRuleName = "UseSqoop"

# HDInsight variables
$hdinsightClusterName = $namePrefix + "hdi"
$defaultStorageAccountName = $namePrefix + "store"
$defaultBlobContainerName = $hdinsightClusterName
#endregion

# Treat all errors as terminating
$ErrorActionPreference = "Stop"

#region - Connect to Azure subscription
Write-Host "`nConnecting to your Azure subscription ..." -ForegroundColor Green
try{Get-AzureRmContext}
catch{
    Login-AzureRmAccount -EnvironmentName AzureChinaCloud
    Select-AzureRmSubscription -SubscriptionId $subscriptionID
}
#endregion

#region - Create Azure resouce group
Write-Host "`nCreating an Azure resource group ..." -ForegroundColor Green
try{
    Get-AzureRmResourceGroup -Name $resourceGroupName
}
catch{
    New-AzureRmResourceGroup -Name $resourceGroupName -Location $location
}
#endregion

#region - Create Azure SQL database server
Write-Host "`nCreating an Azure SQL Database server ..." -ForegroundColor Green
try{
    Get-AzureRmSqlServer -ServerName $sqlDatabaseServerName -ResourceGroupName $resourceGroupName}
catch{
    Write-Host "`nCreating SQL Database server ..."  -ForegroundColor Green

    $sqlDatabasePW = ConvertTo-SecureString -String $sqlDatabasePassword -AsPlainText -Force
    $sqlLoginCredentials = New-Object System.Management.Automation.PSCredential($sqlDatabaseLogin,$sqlDatabasePW)

    $sqlDatabaseServerName = (New-AzureRmSqlServer `
                                -ResourceGroupName $resourceGroupName `
                                -ServerName $sqlDatabaseServerName `
                                -SqlAdministratorCredentials $sqlLoginCredentials `
                                -Location $location).ServerName
    Write-Host "`tThe new SQL database server name is $sqlDatabaseServerName." -ForegroundColor Cyan

    Write-Host "`nCreating firewall rule, $fireWallRuleName ..." -ForegroundColor Green
    $workstationIPAddress = Invoke-RestMethod $ipAddressRestService
    New-AzureRmSqlServerFirewallRule `
        -ResourceGroupName $resourceGroupName `
        -ServerName $sqlDatabaseServerName `
        -FirewallRuleName "$fireWallRuleName-workstation" `
        -StartIpAddress $workstationIPAddress `
        -EndIpAddress $workstationIPAddress

    #To allow other Azure services to access the server add a firewall rule and set both the StartIpAddress and EndIpAddress to 0.0.0.0. 
    #Note that this allows Azure traffic from any Azure subscription to access the server.
    New-AzureRmSqlServerFirewallRule `
        -ResourceGroupName $resourceGroupName `
        -ServerName $sqlDatabaseServerName `
        -FirewallRuleName "$fireWallRuleName-Azureservices" `
        -StartIpAddress "0.0.0.0" `
        -EndIpAddress "0.0.0.0"
}
#endregion

#region - Create and validate Azure SQL database
Write-Host "`nCreating SQL Database, $sqlDatabaseName ..."  -ForegroundColor Green

try {
    Get-AzureRmSqlDatabase `
        -ResourceGroupName $resourceGroupName `
        -ServerName $sqlDatabaseServerName `
        -DatabaseName $sqlDatabaseName
}
catch {
    New-AzureRMSqlDatabase `
        -ResourceGroupName $resourceGroupName `
        -ServerName $sqlDatabaseServerName `
        -DatabaseName $sqlDatabaseName `
        -Edition "Standard" `
        -RequestedServiceObjectiveName "S1"
}
#endregion

#region - Create SQL database tables
Write-Host "Creating the log4jlogs table  ..." -ForegroundColor Green

$sqlDatabaseTableName = "log4jLogsCount"
$cmdCreateLog4jCountTable = " CREATE TABLE [dbo].[$sqlDatabaseTableName](
        [Level] [nvarchar](10) NOT NULL,
        [Total] float,
    CONSTRAINT [PK_$sqlDatabaseTableName] PRIMARY KEY CLUSTERED
    (
    [Level] ASC
    )
    )"

$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = $sqlDatabaseConnectionString
$conn.Open()

# Create the log4jlogs table and index
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.Connection = $conn
$cmd.CommandText = $cmdCreateLog4jCountTable
$cmd.ExecuteNonQuery()

$conn.close()
#endregion

#region - Create HDInsight cluster

Write-Host "Creating the HDInsight cluster and the dependent services ..." -ForegroundColor Green

# Create the default storage account
New-AzureRmStorageAccount `
    -ResourceGroupName $resourceGroupName `
    -Name $defaultStorageAccountName `
    -Location $location `
    -Type Standard_LRS

# Create the default Blob container
$defaultStorageAccountKey = (Get-AzureRmStorageAccountKey `
                                -ResourceGroupName $resourceGroupName `
                                -Name $defaultStorageAccountName)[0].Value
$defaultStorageAccountContext = New-AzureStorageContext `
                                    -StorageAccountName $defaultStorageAccountName `
                                    -StorageAccountKey $defaultStorageAccountKey 
New-AzureStorageContainer `
    -Name $defaultBlobContainerName `
    -Context $defaultStorageAccountContext 

# Create the HDInsight cluster
$pw = ConvertTo-SecureString -String $httpPassword -AsPlainText -Force
$httpCredential = New-Object System.Management.Automation.PSCredential($httpUserName,$pw)

New-AzureRmHDInsightCluster `
    -ResourceGroupName $resourceGroupName `
    -ClusterName $HDInsightClusterName `
    -Location $location `
    -ClusterType Hadoop `
    -OSType Windows `
    -ClusterSizeInNodes 2 `
    -HttpCredential $httpCredential `
    -DefaultStorageAccountName "$defaultStorageAccountName.blob.core.chinacloudapi.cn" `
    -DefaultStorageAccountKey $defaultStorageAccountKey `
    -DefaultStorageContainer $defaultBlobContainerName 

# Validate the cluster
Get-AzureRmHDInsightCluster -ClusterName $hdinsightClusterName
#endregion

#region - copy Oozie workflow and HiveQL files

Write-Host "Copy workflow definition and HiveQL script file ..." -ForegroundColor Green

# Both files are stored in a public Blob
$publicBlobContext = New-AzureStorageContext -StorageAccountName "hditutorialdata" -Anonymous

# WASB folder for storing the Oozie tutorial files.
$destFolder = "tutorials/useoozie"  # Do NOT use the long path here

Start-CopyAzureStorageBlob `
    -Context $publicBlobContext `
    -SrcContainer "useoozie" `
    -SrcBlob "useooziewf.hql"  `
    -DestContext $defaultStorageAccountContext `
    -DestContainer $defaultBlobContainerName `
    -DestBlob "$destFolder/useooziewf.hql" `
    -Force

Start-CopyAzureStorageBlob `
    -Context $publicBlobContext `
    -SrcContainer "useoozie" `
    -SrcBlob "workflow.xml"  `
    -DestContext $defaultStorageAccountContext `
    -DestContainer $defaultBlobContainerName `
    -DestBlob "$destFolder/workflow.xml" `
    -Force

#validate the copy
Get-AzureStorageBlob `
    -Context $defaultStorageAccountContext `
    -Container $defaultBlobContainerName `
    -Blob $destFolder/workflow.xml

Get-AzureStorageBlob `
    -Context $defaultStorageAccountContext `
    -Container $defaultBlobContainerName `
    -Blob $destFolder/useooziewf.hql

#endregion

#region - copy the sample.log file

Write-Host "Make a copy of the sample.log file ... " -ForegroundColor Green

Start-CopyAzureStorageBlob `
    -Context $defaultStorageAccountContext `
    -SrcContainer $defaultBlobContainerName `
    -SrcBlob "example/data/sample.log"  `
    -DestContext $defaultStorageAccountContext `
    -DestContainer $defaultBlobContainerName `
    -destBlob "$destFolder/data/sample.log" 

#validate the copy
Get-AzureStorageBlob `
    -Context $defaultStorageAccountContext `
    -Container $defaultBlobContainerName `
    -Blob $destFolder/data/sample.log

#endregion

#region - submit Oozie job

$storageUri="wasb://$defaultBlobContainerName@$defaultStorageAccountName.blob.core.chinacloudapi.cn"

$oozieJobName = $namePrefix + "OozieJob"

#Oozie WF variables
$oozieWFPath="$storageUri/tutorials/useoozie"  # The default name is workflow.xml. And you don't need to specify the file name.
$waitTimeBetweenOozieJobStatusCheck=10

#Hive action variables
$hiveScript = "$storageUri/tutorials/useoozie/useooziewf.hql"
$hiveTableName = "log4jlogs"
$hiveDataFolder = "$storageUri/tutorials/useoozie/data"
$hiveOutputFolder = "$storageUri/tutorials/useoozie/output"

#Sqoop action variables
$sqlDatabaseConnectionString = "jdbc:sqlserver://$sqlDatabaseServerName.database.chinacloudapi.cn;user=$sqlDatabaseLogin@$sqlDatabaseServerName;password=$sqlDatabasePassword;database=$sqlDatabaseName"

$OoziePayload =  @"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<property>
    <name>nameNode</name>
    <value>$storageUrI</value>
</property>

<property>
    <name>jobTracker</name>
    <value>jobtrackerhost:9010</value>
</property>

<property>
    <name>queueName</name>
    <value>default</value>
</property>

<property>
    <name>oozie.use.system.libpath</name>
    <value>true</value>
</property>

<property>
    <name>hiveScript</name>
    <value>$hiveScript</value>
</property>

<property>
    <name>hiveTableName</name>
    <value>$hiveTableName</value>
</property>

<property>
    <name>hiveDataFolder</name>
    <value>$hiveDataFolder</value>
</property>

<property>
    <name>hiveOutputFolder</name>
    <value>$hiveOutputFolder</value>
</property>

<property>
    <name>sqlDatabaseConnectionString</name>
    <value>&quot;$sqlDatabaseConnectionString&quot;</value>
</property>

<property>
    <name>sqlDatabaseTableName</name>
    <value>$SQLDatabaseTableName</value>
</property>

<property>
    <name>user.name</name>
    <value>$httpUserName</value>
</property>

<property>
    <name>oozie.wf.application.path</name>
    <value>$oozieWFPath</value>
</property>

</configuration>
"@

Write-Host "Checking Oozie server status..." -ForegroundColor Green
$clusterUriStatus = "https://$hdinsightClusterName.azurehdinsight.cn:443/oozie/v2/admin/status"
$response = Invoke-RestMethod -Method Get -Uri $clusterUriStatus -Credential $httpCredential -OutVariable $OozieServerStatus

$jsonResponse = ConvertFrom-Json (ConvertTo-Json -InputObject $response)
$oozieServerSatus = $jsonResponse[0].("systemMode")
Write-Host "Oozie server status is $oozieServerSatus."

# create Oozie job
Write-Host "Sending the following Payload to the cluster:" -ForegroundColor Green
Write-Host "`n--------`n$OoziePayload`n--------"
$clusterUriCreateJob = "https://$hdinsightClusterName.azurehdinsight.cn:443/oozie/v2/jobs"
$response = Invoke-RestMethod -Method Post -Uri $clusterUriCreateJob -Credential $httpCredential -Body $OoziePayload -ContentType "application/xml" -OutVariable $OozieJobName #-debug

$jsonResponse = ConvertFrom-Json (ConvertTo-Json -InputObject $response)
$oozieJobId = $jsonResponse[0].("id")
Write-Host "Oozie job id is $oozieJobId..."

# start Oozie job
Write-Host "Starting the Oozie job $oozieJobId..." -ForegroundColor Green
$clusterUriStartJob = "https://$hdinsightClusterName.azurehdinsight.cn:443/oozie/v2/job/" + $oozieJobId + "?action=start"
$response = Invoke-RestMethod -Method Put -Uri $clusterUriStartJob -Credential $httpCredential | Format-Table -HideTableHeaders #-debug

# get job status
Write-Host "Sleeping for $waitTimeBetweenOozieJobStatusCheck seconds until the job metadata is populated in the Oozie metastore..." -ForegroundColor Green
Start-Sleep -Seconds $waitTimeBetweenOozieJobStatusCheck

Write-Host "Getting job status and waiting for the job to complete..." -ForegroundColor Green
$clusterUriGetJobStatus = "https://$hdinsightClusterName.azurehdinsight.cn:443/oozie/v2/job/" + $oozieJobId + "?show=info"
$response = Invoke-RestMethod -Method Get -Uri $clusterUriGetJobStatus -Credential $httpCredential
$jsonResponse = ConvertFrom-Json (ConvertTo-Json -InputObject $response)
$JobStatus = $jsonResponse[0].("status")

while($JobStatus -notmatch "SUCCEEDED|KILLED")
{
    Write-Host "$(Get-Date -format 'G'): $oozieJobId is in $JobStatus state...waiting $waitTimeBetweenOozieJobStatusCheck seconds for the job to complete..."
    Start-Sleep -Seconds $waitTimeBetweenOozieJobStatusCheck
    $response = Invoke-RestMethod -Method Get -Uri $clusterUriGetJobStatus -Credential $httpCredential
    $jsonResponse = ConvertFrom-Json (ConvertTo-Json -InputObject $response)
    $JobStatus = $jsonResponse[0].("status")
    $jobStatus
}

Write-Host "$(Get-Date -format 'G'): $oozieJobId is in $JobStatus state!" -ForegroundColor Green

#endregion

重新运行教程

若要重新运行该工作流,必须删除以下项:

  • Hive 脚本输出文件
  • log4jLogsCount 表中的数据

以下是可以使用的一个示例 PowerShell 脚本:

$resourceGroupName = "<AzureResourceGroupName>"

$defaultStorageAccountName = "<AzureStorageAccountName>"
$defaultBlobContainerName = "<ContainerName>"

#SQL database variables
$sqlDatabaseServerName = "<SQLDatabaseServerName>"
$sqlDatabaseLogin = "<SQLDatabaseLoginName>"
$sqlDatabasePassword = "<SQLDatabaseLoginPassword>"
$sqlDatabaseName = "<SQLDatabaseName>"
$sqlDatabaseTableName = "log4jLogsCount"

Write-host "Delete the Hive script output file ..." -ForegroundColor Green
$defaultStorageAccountKey = (Get-AzureRmStorageAccountKey `
                            -ResourceGroupName $resourceGroupName `
                            -Name $defaultStorageAccountName)[0].Value
$destContext = New-AzureStorageContext -StorageAccountName $defaultStorageAccountName -StorageAccountKey $defaultStorageAccountKey
Remove-AzureStorageBlob -Context $destContext -Blob "tutorials/useoozie/output/000000_0" -Container $defaultBlobContainerName

Write-host "Delete all the records from the log4jLogsCount table ..." -ForegroundColor Green
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Data Source=$sqlDatabaseServerName.database.chinacloudapi.cn;Initial Catalog=$sqlDatabaseName;User ID=$sqlDatabaseLogin;Password=$sqlDatabasePassword;Encrypt=true;Trusted_Connection=false;"
$conn.open()
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.connection = $conn
$cmd.commandtext = "delete from $sqlDatabaseTableName"
$cmd.executenonquery()

$conn.close()

后续步骤

本教程已经介绍了如何定义 Oozie 工作流以及如何使用 PowerShell 运行 Oozie 作业。 若要了解更多信息,请参阅下列文章: