Azure PowerShell을 사용하여 Azure HDInsight에서 Apache Sqoop 작업을 실행하여 HDInsight 클러스터와 Azure SQL Database 또는 SQL Server 간에 데이터를 가져오고 내보내는 방법을 알아봅니다. 이 문서는 HDInsight에서 Hadoop과 함께 Apache Sqoop 사용의 연속입니다.
필수 조건
Azure PowerShell AZ 모듈 이 설치된 워크스테이션.
Sqoop에 익숙해야 합니다. 자세한 내용은 Sqoop 사용자 가이드를 참조하세요.
Sqoop 내보내기
Hive에서 SQL로의 변환.
이 예제에서는 Hive hivesampletable
테이블에서 SQL의 mobiledata
테이블로 데이터를 내보냅니다. 아래 변수의 값을 설정한 다음 명령을 실행합니다.
$hdinsightClusterName = ""
$httpPassword = ''
$sqlDatabasePassword = ''
# These values only need to be changed if the template was not followed.
$httpUserName = "admin"
$sqlServerLogin = "sqluser"
$sqlServerName = $hdinsightClusterName + "dbserver"
$sqlDatabaseName = $hdinsightClusterName + "db"
$pw = ConvertTo-SecureString -String $httpPassword -AsPlainText -Force
$httpCredential = New-Object System.Management.Automation.PSCredential($httpUserName,$pw)
# Connection string
$connectionString = "jdbc:sqlserver://$sqlServerName.database.windows.net;user=$sqlServerLogin@$sqlServerName;password=$sqlDatabasePassword;database=$sqlDatabaseName"
# start export
New-AzHDInsightSqoopJobDefinition `
-Command "export --connect $connectionString --table mobiledata --hcatalog-table hivesampletable" `
| Start-AzHDInsightJob `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential
대체 실행
아래 코드는 동일한 내보내기를 수행합니다. 그러나 출력 로그를 읽는 방법을 제공합니다. 코드를 실행하여 내보내기를 시작합니다.
$sqoopCommand = "export --connect $connectionString --table mobiledata --hcatalog-table hivesampletable" $sqoopDef = New-AzHDInsightSqoopJobDefinition ` -Command $sqoopCommand $sqoopJob = Start-AzHDInsightJob ` -ClusterName $hdinsightClusterName ` -HttpCredential $httpCredential ` -JobDefinition $sqoopDef
아래 코드는 출력 로그를 표시합니다. 아래 코드를 실행합니다.
Get-AzHDInsightJobOutput ` -ClusterName $hdinsightClusterName ` -HttpCredential $httpCredential ` -JobId $sqoopJob.JobId ` -DisplayOutputType StandardError Get-AzHDInsightJobOutput ` -ClusterName $hdinsightClusterName ` -HttpCredential $httpCredential ` -JobId $sqoopJob.JobId ` -DisplayOutputType StandardOutput
오류 메시지가 The specified blob does not exist.
표시되면 몇 분 후에 다시 시도하세요.
Sqoop 가져오기
SQL에서 Azure Storage로. 이 예제에서는 SQL의 mobiledata
테이블에서 HDInsight의 wasb:///tutorials/usesqoop/importeddata
디렉터리로 데이터를 가져옵니다. 데이터의 필드는 탭 문자로 구분되어 있으며 줄은 줄 바꿈 문자로 종료됩니다. 이 예제에서는 이전 예제를 완료한 것으로 가정합니다.
$sqoopCommand = "import --connect $connectionString --table mobiledata --target-dir wasb:///tutorials/usesqoop/importeddata --fields-terminated-by '\t' --lines-terminated-by '\n' -m 1"
$sqoopDef = New-AzHDInsightSqoopJobDefinition `
-Command $sqoopCommand
$sqoopJob = Start-AzHDInsightJob `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential `
-JobDefinition $sqoopDef
Get-AzHDInsightJobOutput `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential `
-JobId $sqoopJob.JobId `
-DisplayOutputType StandardError
Get-AzHDInsightJobOutput `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential `
-JobId $sqoopJob.JobId `
-DisplayOutputType StandardOutput
추가 Sqoop 내보내기 예제
기본 스토리지 계정에서 /tutorials/usesqoop/data/sample.log
데이터를 내보낸 다음 SQL Server 데이터베이스에서 호출 log4jlogs
된 테이블로 가져오는 강력한 예제입니다. 이 예제는 이전 예제에 종속되지 않습니다.
다음 PowerShell 스크립트는 원본 파일을 미리 처리한 다음 테이블 log4jlogs
로 내보냅니다.
CLUSTERNAME
, CLUSTERPASSWORD
, SQLPASSWORD
를 필수 구성 요소에서 사용한 값으로 바꾸십시오.
<#------ BEGIN USER INPUT ------#>
$hdinsightClusterName = "CLUSTERNAME"
$httpUserName = "admin" #default is admin, update as needed
$httpPassword = 'CLUSTERPASSWORD'
$sqlDatabasePassword = 'SQLPASSWORD'
<#------- END USER INPUT -------#>
# Other fixed variable that should be used as is
$sqlServerName = $hdinsightClusterName + "dbserver"
$sqlDatabaseName = $hdinsightClusterName + "db"
$tableName_log4j = "log4jlogs"
$exportDir_log4j = "/tutorials/usesqoop/data"
$sourceBlobName = "example/data/sample.log"
$destBlobName = "tutorials/usesqoop/data/sample.log"
$sqljdbcdriver = "/user/oozie/share/lib/sqoop/mssql-jdbc-7.0.0.jre8.jar"
$cluster = Get-AzHDInsightCluster -ClusterName $hdinsightClusterName
$defaultStorageAccountName = $cluster.DefaultStorageAccount -replace '.blob.core.windows.net'
$defaultStorageContainer = $cluster.DefaultStorageContainer
$resourceGroup = $cluster.ResourceGroup
$sqlServer = Get-AzSqlServer -ResourceGroupName $resourceGroup -ServerName $sqlServerName
$sqlServerLogin = $sqlServer.SqlAdministratorLogin
$sqlServerFQDN = $sqlServer.FullyQualifiedDomainName
#Connect to Azure subscription
Write-Host "`nConnecting to your Azure subscription ..." -ForegroundColor Green
try{Get-AzContext}
catch{Connect-AzAccount}
#pre-process the source file
Write-Host "`nPreprocessing the source file ..." -ForegroundColor Green
# This procedure creates a new file with $destBlobName
# Define the connection string
$defaultStorageAccountKey = (Get-AzStorageAccountKey `
-ResourceGroupName $resourceGroup `
-Name $defaultStorageAccountName)[0].Value
# Create block blob objects referencing the source and destination blob.
$storageAccount = Get-AzStorageAccount `
-ResourceGroupName $resourceGroup `
-Name $defaultStorageAccountName
$storageContainer = ($storageAccount |Get-AzStorageContainer -Name $defaultStorageContainer).CloudBlobContainer
$sourceBlob = $storageContainer.GetBlockBlobReference($sourceBlobName)
$destBlob = $storageContainer.GetBlockBlobReference($destBlobName)
# Define a MemoryStream and a StreamReader for reading from the source file
$stream = New-Object System.IO.MemoryStream
$stream = $sourceBlob.OpenRead()
$sReader = New-Object System.IO.StreamReader($stream)
# Define a MemoryStream and a StreamWriter for writing into the destination file
$memStream = New-Object System.IO.MemoryStream
$writeStream = New-Object System.IO.StreamWriter $memStream
# Pre-process the source blob
$exString = "java.lang.Exception:"
while(-Not $sReader.EndOfStream){
$line = $sReader.ReadLine()
$split = $line.Split(" ")
# remove the "java.lang.Exception" from the first element of the array
# for example: java.lang.Exception: 2012-02-03 19:11:02 SampleClass8 [WARN] problem finding id 153454612
if ($split[0] -eq $exString){
#create a new ArrayList to remove $split[0]
$newArray = [System.Collections.ArrayList] $split
$newArray.Remove($exString)
# update $split and $line
$split = $newArray
$line = $newArray -join(" ")
}
# remove the lines that has less than 7 elements
if ($split.count -ge 7){
write-host $line
$writeStream.WriteLine($line)
}
}
# Write to the destination blob
$writeStream.Flush()
$memStream.Seek(0, "Begin")
$destBlob.UploadFromStream($memStream)
#export the log file from the cluster to SQL
Write-Host "Exporting the log file ..." -ForegroundColor Green
$pw = ConvertTo-SecureString -String $httpPassword -AsPlainText -Force
$httpCredential = New-Object System.Management.Automation.PSCredential($httpUserName,$pw)
# Connection string
$connectionString = "jdbc:sqlserver://$sqlServerFQDN;user=$sqlServerLogin@$sqlServerName;password=$sqlDatabasePassword;database=$sqlDatabaseName"
# Submit a Sqoop job
$sqoopDef = New-AzHDInsightSqoopJobDefinition `
-Command "export --connect $connectionString --table $tableName_log4j --export-dir $exportDir_log4j --input-fields-terminated-by \0x20 -m 1" `
-Files $sqljdbcdriver
$sqoopJob = Start-AzHDInsightJob `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential `
-JobDefinition $sqoopDef
Wait-AzHDInsightJob `
-ResourceGroupName $resourceGroup `
-ClusterName $hdinsightClusterName `
-HttpCredential $httpCredential `
-JobId $sqoopJob.JobId
Write-Host "Standard Error" -BackgroundColor Green
Get-AzHDInsightJobOutput `
-ResourceGroupName $resourceGroup `
-ClusterName $hdinsightClusterName `
-DefaultStorageAccountName $defaultStorageAccountName `
-DefaultStorageAccountKey $defaultStorageAccountKey `
-DefaultContainer $defaultStorageContainer `
-HttpCredential $httpCredential `
-JobId $sqoopJob.JobId `
-DisplayOutputType StandardError
Write-Host "Standard Output" -BackgroundColor Green
Get-AzHDInsightJobOutput `
-ResourceGroupName $resourceGroupName `
-ClusterName $hdinsightClusterName `
-DefaultStorageAccountName $defaultStorageAccountName `
-DefaultStorageAccountKey $defaultStorageAccountKey `
-DefaultContainer $defaultStorageContainer `
-HttpCredential $httpCredential `
-JobId $sqoopJob.JobId `
-DisplayOutputType StandardOutput
제한점
Linux 기반 HDInsight에는 다음과 같은 제한 사항이 있습니다.
대량 내보내기: SQL로 데이터를 내보내는 데 사용되는 Sqoop 커넥터는 현재 대량 삽입을 지원하지 않습니다.
일괄 처리: 삽입을
-batch
수행할 때 스위치를 사용하여 Sqoop은 삽입 작업을 일괄 처리하는 대신 여러 삽입을 수행합니다.
다음 단계
이제 Sqoop을 사용하는 방법에 대해 알아봤습니다. 자세한 내용은 다음을 참조하세요.
- HDInsight와 함께 Apache Oozie 사용: Oozie 워크플로에서 Sqoop 작업을 사용합니다.
- HDInsight에 데이터 업로드: HDInsight 또는 Azure Blob Storage에 데이터를 업로드하는 다른 방법을 찾습니다.