Desenvolvimento de ação de script com o HDInsight
Saiba como personalizar o cluster HDInsight usando scripts Bash. 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 em nós de cluster para fazer alterações de configuração ou para instalar software. A Ação de Script é executada como raiz e concede direitos de acesso completo a nós do cluster.
As ações de script podem ser aplicadas por meio 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 do .NET do HDInsight | ✓ | ✓ |
Modelo do Azure Resource Manager | ✓ |
Para saber mais sobre o uso desses métodos para aplicar ações de script, confira Personalizar clusters HDInsight usando ações de script.
Práticas recomendadas para o desenvolvimento de scripts
Ao desenvolver um script personalizado para um cluster HDInsight, há várias práticas recomendadas para se considerar:
- Direcionar para a versão do Apache Hadoop
- Direcionar para a versão do sistema operacional
- Fornecer links estáveis para recursos de script
- Usar os recursos pré-compilados
- Certifique-se de que o script de personalização do cluster seja idempotente
- Garantir alta disponibilidade da arquitetura de cluster
- Configurar os componentes personalizados para usar armazenamento de Blob do Azure
- Gravar informações para STDOUT e STDERR
- Salvar arquivos como ASCII com terminações de linha LF
- Usar a lógica de repetição para recuperar-se de erros transitórios
Importante
Ações de script devem ser concluídas em 60 minutos ou o processo falha. Durante o provisionamento de 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 rede, pode fazer com que o script leve mais tempo para ser concluído comparado ao seu tempo de conclusão no ambiente de desenvolvimento.
Direcionar para a versão do Apache Hadoop
Diferentes versões do HDInsight têm diferentes versões de componentes e serviços do Hadoop instaladas. Se seu script espera uma versão específica de um serviço ou componente, você deve usar somente o script com a versão do HDInsight que inclui os componentes necessários. Você pode encontrar informações sobre versões dos componentes incluídos com o HDInsight usando o documento Controle de versão de componente do HDInsight .
Verificando a versão do sistema operacional
Versões diferentes do HDInsight contam com versões específicas do Ubuntu. Pode haver diferenças entre as versões de sistema operacional, que você deve verificar em seu script. Por exemplo, talvez seja necessário instalar um binário que esteja vinculado à versão do Ubuntu.
Para verificar a versão do sistema operacional, use lsb_release
. Por exemplo, o script de exemplo a seguir demonstra como fazer referência a um arquivo tar específico dependendo da versão do SO:
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
Segmentar a versão do sistema operacional
O Azure HDInsight baseia-se na distribuição do Ubuntu do Linux. Versões diferentes do HDInsight contam com versões diferentes do Ubuntu, o que pode afetar o comportamento do seu script. Por exemplo, HDInsight 3.4 e versões mais recentes são baseados em versões do Ubuntu que usam o Upstart. As versões 3.5 e posteriores se baseiam no Ubuntu 16.04, que usa Systemd
. Systemd
e Upstart contam com comandos diferentes, portanto seu script deve ser escrito para funcionar com ambos.
Outra diferença importante entre o HDInsight 3.4 e o 3.5 é que o 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 snippets de código em https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.
Para a versão do Ubuntu, que é usada pelo HDInsight, consulte o documento Versão do componente HDInsight.
Para entender as diferenças entre Systemd
e Upstart, consulte Systemd
para usuários do Upstart.
Fornecer links estáveis para recursos de script
O script e recursos associados devem permanecer disponíveis durante o tempo de vida do cluster. Esses recursos serão necessários se novos nós forem adicionados ao cluster durante as operações de dimensionamento.
A melhor prática é 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 então em 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 armazenamento https://hdiconfigactions.blob.core.windows.net/
. Esse local é um contêiner público somente leitura mantido pela equipe do HDInsight.
Usar os recursos pré-compilados
Para reduzir o tempo necessário de execução do script, evite operações que compilem recursos do código-fonte. Por exemplo, pré-compile recursos e armazene-os em um blob da conta de Armazenamento do Azure no mesmo data center que o HDInsight.
Certifique-se de que o script de personalização do cluster seja idempotente
Os scripts devem ser idempotentes. Se o script for executado várias vezes, ele deverá retornar o cluster ao mesmo estado a cada vez.
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 de cabeçalho que estão ativos dentro do cluster; as ações de script são executadas em ambos esses nós. Se os componentes de que instalação esperam apenas um nó principal, não instale os componentes em ambos os nós de cabeçalho.
Importante
Os serviços fornecidos como parte do HDInsight são projetados para failover entre os dois nós de cabeçalho, conforme necessário. Essa funcionalidade não se estende a componentes personalizados instalados por meio de ações de script. Se você precisar de alta disponibilidade para componentes personalizados, você deverá implementar seu próprio mecanismo de failover.
Configurar os componentes personalizados para usar armazenamento de Blob do Azure
Os componentes que você instala no cluster podem ter uma configuração padrão que usa o armazenamento HDFS (Sistema de Arquivos Distribuído do Apache Hadoop). O HDInsight usa o Armazenamento de Blobs do Azure ou o Azure Data Lake Storage como o repositório padrão. Ambos fornecem um sistema de arquivos compatível com HDFS que faz os dados persistirem mesmo que o cluster seja excluído. Talvez você precise configurar os componentes instalados para usar o WASB ou ADL em vez de HDFS.
Para a maioria das operações, você não precisa especificar o sistema de arquivos. Por exemplo, o arquivo hadoop-common.jar é copiado do sistema de arquivos local para o armazenamento de cluster no exemplo a seguir:
hdfs dfs -put /usr/hdp/current/hadoop-client/hadoop-common.jar /example/jars/
Neste exemplo, o comando hdfs
usa o armazenamento de cluster padrão de modo transparente. Para algumas operações, talvez seja necessário especificar o URI. Por exemplo, adl:///example/jars
para Azure Data Lake Storage Gen1, abfs:///example/jars
para Data Lake Storage Gen2 ou wasb:///example/jars
para Azure Storage.
Gravar informações para STDOUT e STDERR
HDInsight registra em log a saída do script que é gravada para STDOUT e STDERR. Você pode exibir essas informações usando a interface do usuário da Web do Ambari.
Observação
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 Solução de problemas de ações de script para conhecer outras maneiras de acessar informações registradas em log.
A maioria dos pacotes de instalação e utilitários já grava informações para STDOUT e STDERR; no entanto, talvez você queira adicionar registro em 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"
Isso redireciona as informações gravadas em STDOUT para STDERR (2) em vez disso. Para obter mais informações sobre 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 em log por ações de script, consulte solucionar problemas de ações de script.
Salvar arquivos como ASCII com terminações de linha LF
Scripts de Bash devem ser armazenados com formato ASCII, com linhas terminadas em LF. Os arquivos que são armazenados como UTF-8 ou usam CRLF como o terminação de linha podem falhar com o seguinte erro:
$'\r': command not found
line 1: #!/usr/bin/env: No such file or directory
Usar a lógica de repetição para recuperar-se de erros transitórios
Quando você baixa arquivos de instalação de pacotes usando apt-get ou outras ações que transmitem dados pela Internet, a ação pode falhar devido a erros de rede temporá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 o script resistente a erros transitórios, você pode implementar lógica de repetição. A função a seguir demonstra como implementar a lógica de repetição. Ela tenta realizar a operação novamente 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 da Ação de Script são utilitários que podem ser usados durante a gravação de scripts personalizados. Esses métodos estão contidos no script https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh. Use o seguinte para baixá-los e usá-los como parte do 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 auxiliares a seguir, disponíveis para uso em seu script:
Uso do auxiliar | Descrição |
---|---|
download_file SOURCEURL DESTFILEPATH [OVERWRITE] |
Baixa um arquivo da URI de origem para o caminho de 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 for executado em um nó de cabeçalho do cluster, retornará 1. Caso contrário, 0. |
test_is_datanode |
Se o nó atual é um nó de dados (de trabalho), retorna 1; caso contrário, 0. |
test_is_first_datanode |
Se o nó atual é o primeiro nó de dados (de trabalho, chamado workernode0), retorna 1; caso contrário, retorna 0. |
get_headnodes |
Retorna o nome de domínio totalmente qualificado dos nós de cabeçalho no cluster. Os nomes são delimitados por vírgula. Uma cadeia de caracteres vazia retorna em caso de erro. |
get_primary_headnode |
Obtém o nome de domínio totalmente qualificado do nó de cabeçalho primário. Uma cadeia de caracteres vazia retorna em caso de erro. |
get_secondary_headnode |
Obtém o nome de domínio totalmente qualificado do nó de cabeçalho secundário. Uma cadeia de caracteres vazia retorna em caso de erro. |
get_primary_headnode_number |
Obtém o sufixo numérico do nó de cabeçalho primário. Uma cadeia de caracteres vazia retorna em caso de erro. |
get_secondary_headnode_number |
Obtém o sufixo numérico do nó de cabeçalho secundário. Uma cadeia de caracteres vazia retorna em caso de erro. |
Padrões comuns de uso
Esta seção fornece orientações sobre como implementar alguns dos padrões comuns de uso que você pode encontrar ao escrever seu próprio script personalizado.
Passando parâmetros para um script
Em alguns casos, seu script pode exigir parâmetros. Por exemplo, a senha do administrador para o cluster talvez seja necessária 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 a $1
para o primeiro parâmetro, $2
para o segundo e assim por diante. $0
contém o nome do próprio script.
Valores passados para o script como parâmetros devem ser inseridos entre aspas simples ('). Isso garante que o valor passado seja tratado como um literal.
Configurando variáveis de ambiente
Definir uma variável de ambiente é uma ação realizada 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 denominada PASSWORD, use a seguinte instrução:
PASSWORD=$1
O acesso subsequente às informações poderia, então, usar $PASSWORD
.
Variáveis de ambiente definidas no script existem somente dentro do escopo do script. Em alguns casos, talvez seja necessário adicionar variáveis de ambiente de todo o sistema que persistirão após a conclusão do script. Para adicionar variáveis de ambiente de todo o sistema, adicione a variável a /etc/environment
. Por exemplo, a instrução a seguir retornará HADOOP_CONF_DIR
:
echo "HADOOP_CONF_DIR=/etc/hadoop/conf" | sudo tee -a /etc/environment
Acesso a locais onde estão armazenados os scripts personalizados
Scripts usados para personalizar um cluster devem ser armazenados em um dos seguintes locais:
Uma conta de armazenamento do Azure associada ao cluster.
Um conta de armazenamento adicional associada ao cluster.
Um URI que pode ser lido publicamente. Por exemplo, uma URL para dados armazenados no OneDrive, Dropbox ou outro serviço de hospedagem de arquivos.
Uma conta do Azure Data Lake Storage que está associada com o cluster do HDInsight. Para obter mais informações sobre como usar o Azure Data Lake Storage com HDInsight, consulte o Guia de início rápido: configurar clusters no HDInsight.
Observação
A entidade de serviço que HDInsight usa para acessar o Data Lake Storage deve ter acesso de leitura para o script.
Recursos usados pelo script também devem estar publicamente disponíveis.
Armazenar os arquivos em uma conta de Armazenamento do Azure ou Azure Data Lake Storage fornece acesso rápido, pois ambos estão dentro da rede do Azure.
Observação
O formato de URI usado para referenciar o script difere dependendo do serviço que está sendo usado. Para contas de armazenamento associadas ao cluster HDInsight, use wasb://
ou wasbs://
. Para URIs lidas publicamente, use http://
ou https://
. Para o Data Lake Storage, use adl://
.
Lista de verificação para implantação de uma ação de script
Aqui estão as etapas que realizamos para se preparar para implantar um script:
- Coloque os arquivos que contêm os scripts personalizados em um local que seja acessível pelos nós de cluster durante a implantação. Por exemplo, o armazenamento padrão para o cluster. Arquivos também podem ser armazenados nos serviços de hospedagem legíveis publicamente.
- Verifique se o script está idempotente. Isso permite que o script seja executado várias vezes no mesmo nó.
- Use um diretório de arquivos temporário, /tmp, para manter os arquivos baixados usados pelos scripts e em seguida limpá-los, depois de os scripts terem sido executados.
- Se as configurações de nível de SO ou arquivos de configuração de serviço do Hadoop forem alterados, será conveniente reiniciar os serviços do HDInsight.
Como executar uma Ação de Script
Você pode usar ações de script para personalizar os clusters HDInsight usando os seguintes métodos:
- Portal do Azure
- Azure PowerShell
- Modelos do Azure Resource Manager
- O SDK .NET do HDInsight.
Para obter mais informações sobre como usar cada método, consulte Como usar a ação de script.
Exemplos de script personalizado
A Microsoft fornece scripts de exemplo para instalar componentes em um cluster HDInsight. Consulte instalar e usar o matiz em clusters do Azure HDInsight como uma ação de script de exemplo.
Solução de problemas
Estes são erros que você pode encontrar ao usar scripts desenvolvidos por você:
Erro: $'\r': command not found
. Às vezes, seguido por syntax error: unexpected end of file
.
Causa: este erro é gerado quando as linhas em um script terminam com CRLF. Os sistemas UNIX esperam apenas LF como terminação da linha.
Esse problema ocorre geralmente quando o script é criado em um ambiente Windows, já que CRLF é uma terminação de linha comum para muitos editores de texto no Windows.
Solução: se for uma opção em seu editor de texto, selecione o formato Unix ou LF para terminação de linha. Você também pode usar os seguintes comandos em um sistema Unix para alterar o CRLF para um LF:
Observação
Os comandos a seguir são a grosso modo equivalentes, no sentido que ambos devem alterar as terminações de linha CRLF para LF. Selecione um deles com base nos utilitários disponíveis no sistema.
Comando | Observações |
---|---|
unix2dos -b INFILE |
O backup do arquivo original é feito com uma extensão .BAK |
tr -d '\r' < INFILE > OUTFILE |
OUTFILE contém uma versão apenas com 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 apenas com 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 BOM (Marca de Ordem de Byte).
Solução: salve o arquivo como ASCII ou UTF-8, sem nenhuma BOM. 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
com o arquivo que contém a BOM. OUTFILE
deve ser um novo nome de arquivo contendo o script sem a BOM.
Próximas etapas
- Saiba como Personalizar os clusters HDInsight usando a ação de script
- Use a referência do SDK do .NET do HDInsight para saber mais sobre a criação de aplicativos .NET que gerenciam o HDInsight
- Use a API REST do HDInsight para aprender a usar o REST para executar ações de gerenciamento em clusters HDInsight.