使用 PowerShell 在已启用 Entra 的 HDInsight 上使用 Apache Hadoop 运行 MapReduce 作业

本文档提供了使用 Azure PowerShell 在已启用 Entra 的 HDInsight 群集上的 Hadoop 中运行 MapReduce 作业的示例。

先决条件

运行 MapReduce 作业

Azure PowerShell 提供 cmdlet ,使你能够在 HDInsight 上远程运行 MapReduce 作业。 在内部,PowerShell 对已启用 Entra 的 HDInsight 群集上运行的 WebHCat (以前称为 Templeton)进行 REST 调用。

在远程 HDInsight 群集中运行 MapReduce 作业时使用的以下 cmdlet。

Cmdlet (命令行工具) Description
Connect-AzAccount 将 Azure PowerShell 认证到您的 Azure 订阅。
New-AzHDInsightMapReduceJobDefinition 使用指定的 MapReduce 信息创建新的 作业定义
Start-AzHDInsightJob 将作业定义发送到 HDInsight 并启动作业。 返回 作业 对象。
Wait-AzHDInsightJob 使用作业对象检查作业的状态。 它会等待作业完成或等待时间超过设定值。
Get-AzHDInsightJobOutput 用于检索作业的输出。

设置(安全持有者访问令牌)

需要持有者令牌才能发送 cURL 或任何 REST 通信。 可以按照下面提到的步骤获取令牌:

使用以下规范对 OAuth 2.0 令牌终结点执行 HTTP GET 请求:

URL

https://login.chinacloudapi.cn/{Tenant_ID}/oauth2/v2.0/token

身体

参数 Description 必需
授权类型 (grant_type) 必须设置为“client_credentials”
client_ID Entra 应用注册的应用程序(客户端)ID
client_secret 生成的客户端机密或证书
作用域 带有 .default 后缀的资源 URL

cURL 请求

curl --request GET \
  --url https://login.chinacloudapi.cn/{tenant_id}/oauth2/v2.0/token \
  --header 'Content-Type: multipart/form-data' \
  --form grant_type=client_credentials \
  --form client_id={app_id} \
  --form client_secret={client_secret} \
  --form scope=https://{clustername}.clusteraccess.azurehdinsight.cn/.default \

响应

成功的请求返回一个 JSON 对象,其中包含:

  • token_type:始终为“Bearer”
  • expires_in:令牌有效期(以秒为单位)
  • ext_expires_in:延长过期时间(以秒为单位)
  • access_token:用于身份验证的持有者令牌

{
	"token_type": "Bearer",
	"expires_in": 3599,
	"ext_expires_in": 3599,
	"access_token": "eyJ0eXAiOiJKV1iLCJub25jZSI6IkhaZ3lqQ2MxSkxzaXRSbmxzT1FTSHV0bEtBeXhhMU1JTzdyWmluLWF6LUEiLCJhbGciOiJSUzI1NiIsIng1dCI6ImltaTBZMnowZFlLeEJ0dEFxS19UdDVoWUJUayIsImtpZCI6ImltaTBZMnowZFlLeEJ0dEFxS19UdDVoWUJUayJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8wY2QzZGY5OS1lMDJmLTRmZDgtYTdkOC0zYjE5ZWVhZGFiYTUvIiwiaWF0IjoxNzQxMjgzMzUzLCJuYmYiOjE3NDEyODMzNTMsImV4cCI6MTc0MTI4NzI1MywiYWlvIjoiazJSZ1lIRDF1U1R4NGx2bjdmMTdGcXlkZUdwWlBnQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJBenVyZSBIREkgTVNGVCBDbGllbnQiLCJhcHBpZCI6IjAzZDNiNTg5LWFjM2MtNDE4NC1iY2EyLTQ3ZWRiN2Q2ZmVjNiIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzBjZDNkZjk5LWUwMmYtNGZkOC1hN2Q4LTNiMTllZWFkYWJhNS8iLCJpZHR5cCI6ImFwcCIsIm9pZCI6ImQ0NDA3YjQ4LWZmZTctNDJjNS04ZDIwLTdiMTTgwNWE4NCIsInJoIjoiMS5BUnNBbWRfVERDX2cyRS1uMkRzWjdxMnJwUU1BQUFBQUFBQUF3QUFBQUFBQUFBRFlBQUFiQUEuIiwic3ViIjoiZDQ0MDdiNDgtZmZlNy00MmM1LThkMjAtN2IxMzU5ODA1YTg0IiwidGVuYW50X3JlZ2lvbl9zY29wZSI6Ik5BIiwidGlkIjoiMGNkM2RmOTktZTAyZi00ZmQ4LWE3ZDgtM2IxOWVlYWRhYmE1IiwidXRpIjoiLVA1T3JPWGpJVWk0VE12dElTYWRBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiMDk5N2ExZDAtMGQxZC00YWNiLWI0MDgtZDVjYTczMTIxZTkwIl0sInhtc19pZHJlbCI6IjI4IDciLCJ4bXNfdGNkdCI6MTQ4NjM3NDQ2MH0.a9z3ZYyMTRQCoY7dzPYE55DmpNAxqo4a4rrt80A-RpK0NDDAftNkc2hafbLl6gdwEzqRyKc1HExUggFUpKxaLUXc62-u-9emxC12EsNlQYd-ZzG_GRDNoTYrro4RDRL-_gDo2lgBNOi5ZZ4a9UI_pYVvV1b0SBRpgd5bmIV4kI2tDfAVZ1-HMpGscuVkQIy45Tqt4c3gXPoMEZ3UYikbCpErbTNfUFqngE3sARXRV-rB1OMu6ZbN32ijjL-rD8593-IfSpmVDUfE5CMGc-7FuWGOYyUUJmp5AQ1yFpJzqaDBEdPT8kKync1o7eplWXCsPWOnVvAKNf7BuWCRRedBWg"
}

以下步骤演示如何使用这些 cmdlet 在已启用 Entra 的 HDInsight 群集中运行作业。

  1. 使用编辑器,将以下代码另存为 mapreducejob.ps1

    PowerShell

    # Login to your Azure subscription
    $context = Get-AzContext
    if ($context -eq $null) 
    {
        Connect-AzAccount
    }
    $context
    
    # Get cluster info
    $clusterName = Read-Host -Prompt "Enter the HDInsight cluster name"
    $bearerToken = Read-Host -Prompt "Enter the bearer token"
    
    # Get the cluster info so we can get the resource group, storage, etc.
    $clusterInfo = Get-AzHDInsightCluster -ClusterName $clusterName
    $resourceGroup = $clusterInfo.ResourceGroup
    $storageAccountName=$clusterInfo.StorageAccount.split('.')
    $container=$clusterInfo.StorageContainer
    # NOTE: This assumes that the storage account is in the same resource
    #       group as the cluster. If it is not, change the
    #       --ResourceGroupName parameter to the group that contains storage.
    $storageAccountKey=(Get-AzStorageAccountKey -Name $storageAccountName[0] -ResourceGroupName $resourceGroup).Value
    
    # Create a storage context
    $context = New-AzStorageContext -StorageAccountName $storageAccountName[0] -StorageAccountKey $storageAccountKey
    
    # Define the MapReduce job
    # -JarFile = the JAR containing the MapReduce application
    # -ClassName = the class of the application
    # -Arguments = The input file, and the output directory
    $wordCountJobDefinition = @{
        "JarFile" = "/example/jars/hadoop-mapreduce-examples.jar"
        "ClassName" = "wordcount"
        "Arguments" = "/example/data/gutenberg/davinci.txt", "/example/data/WordCountOutput"
    }
    
    # Submit the job to the cluster
    Write-Host "Start the MapReduce job..." -ForegroundColor Green
    $headers = @{
        "Authorization" = "Bearer $bearerToken"
    }
    $wordCountJob = Invoke-RestMethod -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/jobs" -Method Post -Headers $headers -Body ($wordCountJobDefinition | ConvertTo-Json)
    
    # Wait for the job to complete
    Write-Host "Wait for the job to complete..." -ForegroundColor Green
    $jobId = $wordCountJob.id
    while ($true) {
        $jobStatus = Invoke-RestMethod -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/jobs/$jobId" -Method Get -Headers $headers
        if ($jobStatus.status -eq "SUCCEEDED" -or $jobStatus.status -eq "FAILED") {
            break
        }
        Start-Sleep -Seconds 10
    }
    
    # Download the output
    Get-AzStorageBlobContent -Blob 'example/data/WordCountOutput/part-r-00000' -Container $container -Destination output.txt -Context $context
    
    # Print the output of the job
    Invoke-RestMethod -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/jobs/$jobId/stdout" -Method Get -Headers $headers
    
    
  2. 打开新的 Azure PowerShell 命令提示符。 将目录更改为 mapreducejob.ps1 文件的位置,然后使用以下命令运行脚本:

    Azure PowerShell

    .\mapreducejob.ps1
    
    

    运行脚本时,系统会提示输入已启用 Entra 的 HDInsight 群集的名称和访问令牌。 还可能会提示你向 Azure 订阅进行身份验证。

  3. 作业完成后,会收到类似于以下文本的输出:

    输出

    Cluster         : CLUSTERNAME
    ExitCode        : 0
    Name            : wordcount
    PercentComplete : map 100% reduce 100%
    Query           :
    State           : Completed
    StatusDirectory : f1ed2028-afe8-402f-a24b-13cc17858097
    SubmissionTime  : 12/5/2014 8:34:09 PM
    JobID           : job_1415949758166_0071
    
    

    此输出指示作业已成功完成。

[!注意} 如果 ExitCode 是 0 以外的值,请参阅 故障排除。 此示例还会将下载的文件存储在运行脚本的目录中 output.txt 文件。

查看输出

若要查看作业生成的单词和计数,请在文本编辑器中打开 output.txt 文件。

Note

MapReduce 作业的输出文件是不可变的。 因此,如果重新运行此示例,则需要更改输出文件的名称。

故障排除

如果作业完成时未返回任何信息,请查看该作业的错误。 若要查看此作业的错误信息,请将以下命令添加到 mapreducejob.ps1 文件的末尾。 然后保存该文件并重新运行脚本。

PowerShell

# Print the output of the WordCount job.
Write-Host "Display the standard output ..." -ForegroundColor Green

# Define the headers with the bearer token
$headers = @{
    "Authorization" = "Bearer $bearerToken"
}

# Get the job output
$jobOutput = Invoke-RestMethod -Uri "https://$clusterName.azurehdinsight.cn/api/v1/clusters/$clusterName/jobs/$wordCountJob.JobId/stdout" -Method Get -Headers $headers

# Display the output
Write-Host $jobOutput

此 cmdlet 返回在作业运行过程中写入 STDERR 的信息。