Desenvolvimento de ações de script com o HDInsight
Saiba como personalizar seu cluster HDInsight usando scripts Bash. As ações de script são uma maneira de personalizar o HDInsight durante ou após a criação do cluster.
O que são ações de script
As ações de script são scripts Bash que o Azure executa nos nós do cluster para fazer alterações de configuração ou instalar software. Uma ação de script é executada como raiz e fornece direitos de acesso total aos nós do cluster.
As ações de script podem ser aplicadas através dos seguintes métodos:
Use este método para aplicar um script... | Durante a criação do cluster... | Em um cluster em execução... |
---|---|---|
Portal do Azure | ✓ | ✓ |
Azure PowerShell | ✓ | ✓ |
CLI Clássica do Azure | ✓ | |
SDK de .NET do HDInsight | ✓ | ✓ |
Modelo do Azure Resource Manager | ✓ |
Para obter mais informações sobre como usar esses métodos para aplicar ações de script, consulte Personalizar clusters HDInsight usando ações de script.
Práticas recomendadas para desenvolvimento de scripts
Quando você desenvolve um script personalizado para um cluster HDInsight, há várias práticas recomendadas a serem lembradas:
- Direcionar a versão do Apache Hadoop
- Direcione a versão do sistema operacional
- Fornecer links estáveis para recursos de script
- Usar recursos pré-compilados
- Verifique se o script de personalização do cluster é idempotente
- Garantir alta disponibilidade da arquitetura de cluster
- Configurar os componentes personalizados para usar o armazenamento de Blob do Azure
- Escreva informações para STDOUT e STDERR
- Salvar arquivos como ASCII com terminações de linha LF
- Use a lógica de repetição para se recuperar de erros transitórios
Importante
As ações de script devem ser concluídas dentro de 60 minutos ou o processo falhará. Durante o provisionamento do nó, o script é executado simultaneamente com outros processos de instalação e configuração. A competição por recursos como tempo de CPU ou largura de banda de rede pode fazer com que o script demore mais para ser concluído do que em seu ambiente de desenvolvimento.
Direcionar a versão do Apache Hadoop
Versões diferentes do HDInsight têm versões diferentes dos serviços e componentes do Hadoop instalados. Se o script espera uma versão específica de um serviço ou componente, você só deve usar o script com a versão do HDInsight que inclui os componentes necessários. Você pode encontrar informações sobre as versões de componentes incluídas no HDInsight usando o documento de controle de versão de componentes do HDInsight.
Verificando a versão do sistema operacional
Diferentes versões do HDInsight dependem de versões específicas do Ubuntu. Pode haver diferenças entre as versões do sistema operacional que você deve verificar em seu script. Por exemplo, você pode precisar instalar um binário que está vinculado à versão do Ubuntu.
Para verificar a versão do SO, utilize lsb_release
. Por exemplo, o script a seguir demonstra como fazer referência a um arquivo tar específico, dependendo da versão do sistema operacional:
OS_VERSION=$(lsb_release -sr)
if [[ $OS_VERSION == 14* ]]; then
echo "OS version is $OS_VERSION. Using hue-binaries-14-04."
HUE_TARFILE=hue-binaries-14-04.tgz
elif [[ $OS_VERSION == 16* ]]; then
echo "OS version is $OS_VERSION. Using hue-binaries-16-04."
HUE_TARFILE=hue-binaries-16-04.tgz
fi
Direcionar a versão do sistema operacional
O HDInsight é baseado na distribuição Ubuntu Linux. Diferentes versões do HDInsight dependem de diferentes versões do Ubuntu, o que pode mudar o comportamento do seu script. Por exemplo, o HDInsight 3.4 e versões anteriores são baseados em versões do Ubuntu que usam Upstart. As versões 3.5 e superiores são baseadas no Ubuntu 16.04, que usa Systemd
. Systemd
e Upstart dependem de comandos diferentes, então seu script deve ser escrito para funcionar com ambos.
Outra diferença importante entre o HDInsight 3.4 e 3.5 é que JAVA_HOME
agora aponta para o Java 8. O código a seguir demonstra como determinar se o script está sendo executado no Ubuntu 14 ou 16:
OS_VERSION=$(lsb_release -sr)
if [[ $OS_VERSION == 14* ]]; then
echo "OS version is $OS_VERSION. Using hue-binaries-14-04."
HUE_TARFILE=hue-binaries-14-04.tgz
elif [[ $OS_VERSION == 16* ]]; then
echo "OS version is $OS_VERSION. Using hue-binaries-16-04."
HUE_TARFILE=hue-binaries-16-04.tgz
fi
...
if [[ $OS_VERSION == 16* ]]; then
echo "Using systemd configuration"
systemctl daemon-reload
systemctl stop webwasb.service
systemctl start webwasb.service
else
echo "Using upstart configuration"
initctl reload-configuration
stop webwasb
start webwasb
fi
...
if [[ $OS_VERSION == 14* ]]; then
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
elif [[ $OS_VERSION == 16* ]]; then
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
fi
Você pode encontrar o script completo que contém esses trechos em https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.
Para obter a versão do Ubuntu usada pelo HDInsight, consulte o documento de versão do componente HDInsight.
Para entender as diferenças entre Systemd
e Upstart, consulte Systemd
para usuários Upstart.
Fornecer links estáveis para recursos de script
O script e os recursos associados devem permanecer disponíveis durante todo o tempo de vida do cluster. Esses recursos são necessários se novos nós forem adicionados ao cluster durante as operações de dimensionamento.
A prática recomendada é baixar e arquivar tudo em uma conta de Armazenamento do Azure em sua assinatura.
Importante
A conta de armazenamento usada deve ser a conta de armazenamento padrão para o cluster ou um contêiner público somente leitura em qualquer outra conta de armazenamento.
Por exemplo, os exemplos fornecidos pela Microsoft são armazenados na conta de https://hdiconfigactions.blob.core.windows.net/
armazenamento. Esse local é um contêiner público somente leitura mantido pela equipe do HDInsight.
Usar recursos pré-compilados
Para reduzir o tempo necessário para executar o script, evite operações que compilam recursos do código-fonte. Por exemplo, pré-compile recursos e armazene-os em um blob de conta do Armazenamento do Azure no mesmo data center do HDInsight.
Verifique se o script de personalização do cluster é idempotente
Os scripts devem ser idempotentes. Se o script for executado várias vezes, ele deverá retornar o cluster ao mesmo estado todas as vezes.
Se o script for executado várias vezes, o script que modifica os arquivos de configuração não deverá adicionar entradas duplicadas.
Garantir alta disponibilidade da arquitetura de cluster
Os clusters HDInsight baseados em Linux fornecem dois nós principais que estão ativos dentro do cluster e as ações de script são executadas em ambos os nós. Se os componentes instalados esperarem apenas um nó principal, não instale os componentes em ambos os nós principais.
Importante
Os serviços fornecidos como parte do HDInsight são projetados para failover entre os dois nós principais, conforme necessário. Essa funcionalidade não é estendida a componentes personalizados instalados por meio de ações de script. Se você precisar de alta disponibilidade para componentes personalizados, deverá implementar seu próprio mecanismo de failover.
Configurar os componentes personalizados para usar o armazenamento de Blob do Azure
Os componentes instalados no cluster podem ter uma configuração padrão que usa o armazenamento Apache Hadoop Distributed File System (HDFS). O HDInsight usa o Armazenamento do Azure ou o Armazenamento Data Lake como o armazenamento padrão. Ambos fornecem um sistema de arquivos compatível com HDFS que persiste os dados mesmo se o cluster for excluído. Talvez seja necessário configurar os componentes instalados para usar WASB ou ADL em vez de HDFS.
Para a maioria das operações, não é necessário especificar o sistema de arquivos. Por exemplo, o seguinte copia o arquivo hadoop-common.jar do sistema de arquivos local para o armazenamento em cluster:
hdfs dfs -put /usr/hdp/current/hadoop-client/hadoop-common.jar /example/jars/
Neste exemplo, o hdfs
comando usa de forma transparente o armazenamento de cluster padrão. Para algumas operações, talvez seja necessário especificar o URI. Por exemplo, adl:///example/jars
para o Azure Data Lake Storage Gen1, abfs:///example/jars
para o Data Lake Storage Gen2 ou wasb:///example/jars
para o Armazenamento do Azure.
Escreva informações para STDOUT e STDERR
O HDInsight registra a saída de script gravada em STDOUT e STDERR. Você pode visualizar essas informações usando a interface do usuário da Web do Ambari.
Nota
O Apache Ambari só estará disponível se o cluster for criado com êxito. Se você usar uma ação de script durante a criação do cluster e a criação falhar, consulte Solucionar problemas de ações de script para outras maneiras de acessar informações registradas.
A maioria dos utilitários e pacotes de instalação já gravam informações em STDOUT e STDERR, no entanto, você pode querer adicionar log adicional. Para enviar texto para STDOUT, use echo
. Por exemplo:
echo "Getting ready to install Foo"
Por padrão, echo
envia a cadeia de caracteres para STDOUT. Para direcioná-lo para STDERR, adicione >&2
antes de echo
. Por exemplo:
>&2 echo "An error occurred installing Foo"
Em vez disso, redireciona as informações gravadas para STDOUT para STDERR (2). Para obter mais informações sobre o redirecionamento de E/S, consulte https://www.tldp.org/LDP/abs/html/io-redirection.html.
Para obter mais informações sobre como exibir informações registradas por ações de script, consulte Solucionar problemas de ações de script.
Salvar arquivos como ASCII com terminações de linha LF
Os scripts Bash devem ser armazenados no formato ASCII, com linhas terminadas por LF. Arquivos armazenados como UTF-8 ou usar CRLF como terminação de linha podem falhar com o seguinte erro:
$'\r': command not found
line 1: #!/usr/bin/env: No such file or directory
Use a lógica de repetição para se recuperar de erros transitórios
Quando você baixa arquivos, instala pacotes usando apt-get ou outras ações que transmitem dados pela internet, a ação pode falhar devido a erros de rede transitórios. Por exemplo, o recurso remoto com o qual você está se comunicando pode estar em processo de failover para um nó de backup.
Para tornar seu script resiliente a erros transitórios, você pode implementar a lógica de repetição. A função a seguir demonstra como implementar a lógica de repetição. Ele tenta novamente a operação três vezes antes de falhar.
#retry
MAXATTEMPTS=3
retry() {
local -r CMD="$@"
local -i ATTMEPTNUM=1
local -i RETRYINTERVAL=2
until $CMD
do
if (( ATTMEPTNUM == MAXATTEMPTS ))
then
echo "Attempt $ATTMEPTNUM failed. no more attempts left."
return 1
else
echo "Attempt $ATTMEPTNUM failed! Retrying in $RETRYINTERVAL seconds..."
sleep $(( RETRYINTERVAL ))
ATTMEPTNUM=$ATTMEPTNUM+1
fi
done
}
Os exemplos a seguir demonstram como usar essa função.
retry ls -ltr foo
retry wget -O ./tmpfile.sh https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh
Métodos auxiliares para scripts personalizados
Os métodos auxiliares de ação de script são utilitários que você pode usar ao escrever scripts personalizados. Esses métodos estão contidos no https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh script. Use o seguinte para baixá-los e usá-los como parte do seu script:
# Import the helper method module.
wget -O /tmp/HDInsightUtilities-v01.sh -q https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh && source /tmp/HDInsightUtilities-v01.sh && rm -f /tmp/HDInsightUtilities-v01.sh
Os seguintes auxiliares disponíveis para uso em seu script:
Utilização do ajudante | Description |
---|---|
download_file SOURCEURL DESTFILEPATH [OVERWRITE] |
Baixa um arquivo do URI de origem para o caminho do arquivo especificado. Por padrão, ele não substitui um arquivo existente. |
untar_file TARFILE DESTDIR |
Extrai um arquivo tar (usando -xf ) para o diretório de destino. |
test_is_headnode |
Se o script foi executado em um nó principal de cluster, retorne 1; caso contrário, 0. |
test_is_datanode |
Se o nó atual for um nó de dados (trabalhador), retorne um 1; caso contrário, 0. |
test_is_first_datanode |
Se o nó atual for o primeiro nó de dados (trabalhador) (chamado workernode0) retornará um 1; caso contrário, 0. |
get_headnodes |
Retornar o nome de domínio totalmente qualificado dos nós principais no cluster. Os nomes são delimitados por vírgula. Uma cadeia de caracteres vazia é retornada em caso de erro. |
get_primary_headnode |
Obtém o nome de domínio totalmente qualificado do nó principal. Uma cadeia de caracteres vazia é retornada em caso de erro. |
get_secondary_headnode |
Obtém o nome de domínio totalmente qualificado do nó principal secundário. Uma cadeia de caracteres vazia é retornada em caso de erro. |
get_primary_headnode_number |
Obtém o sufixo numérico do nó principal primário. Uma cadeia de caracteres vazia é retornada em caso de erro. |
get_secondary_headnode_number |
Obtém o sufixo numérico do nó principal secundário. Uma cadeia de caracteres vazia é retornada em caso de erro. |
Padrões de utilização comuns
Esta seção fornece orientação sobre como implementar alguns dos padrões de uso comuns que você pode encontrar ao escrever seu próprio script personalizado.
Passando parâmetros para um script
Em alguns casos, o script pode exigir parâmetros. Por exemplo, você pode precisar da senha de administrador para o cluster ao usar a API REST do Ambari.
Os parâmetros passados para o script são conhecidos como parâmetros posicionais e são atribuídos para $1
o primeiro parâmetro, $2
para o segundo e assim por diante. $0
contém o nome do próprio script.
Os valores passados para o script como parâmetros devem ser colocados entre aspas simples ('). Isso garante que o valor passado seja tratado como um literal.
Definindo variáveis de ambiente
A definição de uma variável de ambiente é executada pela seguinte instrução:
VARIABLENAME=value
No exemplo anterior, VARIABLENAME
é o nome da variável. Para acessar a variável, use $VARIABLENAME
. Por exemplo, para atribuir um valor fornecido por um parâmetro posicional como uma variável de ambiente chamada PASSWORD, você usaria a seguinte instrução:
PASSWORD=$1
O acesso subsequente à informação poderia então utilizar $PASSWORD
.
As variáveis de ambiente definidas no script só existem dentro do escopo do script. Em alguns casos, talvez seja necessário adicionar variáveis de ambiente em todo o sistema que persistirão após a conclusão do script. Para adicionar variáveis de ambiente em todo o sistema, adicione a variável ao /etc/environment
. Por exemplo, a seguinte instrução adiciona:HADOOP_CONF_DIR
echo "HADOOP_CONF_DIR=/etc/hadoop/conf" | sudo tee -a /etc/environment
Acesso a locais onde os scripts personalizados são armazenados
Os scripts usados para personalizar um cluster precisam ser armazenados em um dos seguintes locais:
Uma conta de Armazenamento do Azure associada ao cluster.
Uma conta de armazenamento adicional associada ao cluster.
Um URI legível publicamente. Por exemplo, uma URL para dados armazenados no OneDrive, Dropbox ou outro serviço de hospedagem de arquivos.
Uma conta do Armazenamento do Azure Data Lake associada ao cluster HDInsight. Para obter mais informações sobre como usar o Armazenamento do Azure Data Lake com o HDInsight, consulte Guia de início rápido: configurar clusters no HDInsight.
Nota
A entidade de serviço que o HDInsight usa para acessar o Armazenamento Data Lake deve ter acesso de leitura ao script.
Os recursos usados pelo script também devem estar disponíveis publicamente.
Armazenar os arquivos em uma conta de Armazenamento do Azure ou no Armazenamento do Azure Data Lake fornece acesso rápido, como ambos na rede do Azure.
Nota
O formato URI usado para fazer referência ao script difere dependendo do serviço que está sendo usado. Para contas de armazenamento associadas ao cluster HDInsight, use wasb://
ou wasbs://
. Para URIs legíveis publicamente, use http://
ou https://
. Para o Armazenamento Data Lake, use adl://
.
Lista de verificação para implantar uma ação de script
Aqui estão as etapas executadas ao se preparar para implantar um script:
- Coloque os arquivos que contêm os scripts personalizados em um local acessível pelos nós do cluster durante a implantação. Por exemplo, o armazenamento padrão para o cluster. Os arquivos também podem ser armazenados em serviços de hospedagem legíveis publicamente.
- Verifique se o script é idempotente. Isso permite que o script seja executado várias vezes no mesmo nó.
- Use um diretório de arquivo temporário /tmp para manter os arquivos baixados usados pelos scripts e, em seguida, limpá-los após a execução dos scripts.
- Se as configurações no nível do sistema operacional ou os arquivos de configuração do serviço Hadoop forem alterados, convém reiniciar os serviços do HDInsight.
Como executar uma ação de script
Você pode usar ações de script para personalizar clusters HDInsight usando os seguintes métodos:
- Portal do Azure
- Azure PowerShell
- Modelos do Azure Resource Manager
- O SDK do HDInsight .NET.
Para obter mais informações sobre como usar cada método, consulte Como usar a ação de script.
Exemplos de script personalizados
A Microsoft fornece scripts de exemplo para instalar componentes em um cluster HDInsight. Consulte Instalar e usar o Hue em clusters HDInsight como um exemplo de ação de script.
Resolução de Problemas
A seguir estão os erros que você pode encontrar ao usar scripts que você desenvolveu:
Erro: $'\r': command not found
. Às vezes seguido por syntax error: unexpected end of file
.
Causa: Este erro é causado quando as linhas em um script terminam com CRLF. Os sistemas Unix esperam apenas LF como o final da linha.
Esse problema ocorre com mais freqüência quando o script é criado em um ambiente Windows, como CRLF é uma terminação de linha comum para muitos editores de texto no Windows.
Resolução: Se for uma opção no seu editor de texto, selecione o formato Unix ou LF para o final da linha. Você também pode usar os seguintes comandos em um sistema Unix para alterar a CRLF para um LF:
Nota
Os comandos a seguir são aproximadamente equivalentes, pois devem alterar as terminações de linha CRLF para LF. Selecione um com base nos utilitários disponíveis no seu sistema.
Comando | Notas |
---|---|
unix2dos -b INFILE |
O backup do arquivo original é feito com um arquivo . Extensão BAK |
tr -d '\r' < INFILE > OUTFILE |
OUTFILE contém uma versão com apenas terminações LF |
perl -pi -e 's/\r\n/\n/g' INFILE |
Modifica o arquivo diretamente |
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE |
OUTFILE contém uma versão com apenas terminações LF. |
Erro: line 1: #!/usr/bin/env: No such file or directory
.
Causa: Este erro ocorre quando o script foi salvo como UTF-8 com uma marca de ordem de bytes (BOM).
Resolução: salve o arquivo como ASCII ou UTF-8 sem uma lista técnica. Você também pode usar o seguinte comando em um sistema Linux ou Unix para criar um arquivo sem a BOM:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
Substitua INFILE
pelo arquivo que contém a lista técnica. OUTFILE
deve ser um novo nome de arquivo, que contém o script sem a lista técnica.
Próximos passos
- Saiba como personalizar clusters HDInsight usando a ação de script
- Use a referência do SDK do .NET do HDInsight para saber mais sobre como criar aplicativos .NET que gerenciam o HDInsight
- Use a API REST do HDInsight para saber como usar o REST para executar ações de gerenciamento em clusters HDInsight.