Desenvolvimento de ações de script com o HDInsight
Saiba como personalizar o cluster do HDInsight com scripts do Bash. As ações de script são uma forma 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 do 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 de cluster.
As ações de script podem ser aplicadas através dos seguintes métodos:
Utilize este método para aplicar um script... | Durante a criação do cluster... | Num cluster em execução... |
---|---|---|
Portal do Azure | ✓ | ✓ |
Azure PowerShell | ✓ | ✓ |
CLI Clássica do Azure | ✓ | |
HDInsight .NET SDK | ✓ | ✓ |
Modelo do Azure Resource Manager | ✓ |
Para obter mais informações sobre como utilizar estes métodos para aplicar ações de script, veja Personalizar clusters do HDInsight com ações de script.
Melhores práticas para o desenvolvimento de scripts
Quando desenvolve um script personalizado para um cluster do HDInsight, existem várias práticas recomendadas a ter em conta:
- Direcionar a versão do Apache Hadoop
- Direcionar a Versão do SO
- Fornecer ligações estáveis para recursos de script
- Utilizar recursos pré-compilados
- Certifique-se de que o script de personalização do cluster é idempotente
- Garantir a elevada disponibilidade da arquitetura do cluster
- Configurar os componentes personalizados para utilizar o armazenamento de Blobs do Azure
- Escrever informações para STDOUT e STDERR
- Guardar ficheiros como ASCII com terminações de linha LF
- Utilizar a lógica de repetição para recuperar de erros transitórios
Importante
As ações de script têm de ser concluídas dentro de 60 minutos ou o processo falha. Durante o aprovisionamento de nós, o script é executado em simultâneo com outros processos de configuração e configuração. A concorrência para recursos como o tempo da CPU ou a largura de banda de rede pode fazer com que o script dedure mais tempo a concluir do que no seu ambiente de desenvolvimento.
Direcionar a versão do Apache Hadoop
Diferentes versões do HDInsight têm versões diferentes de serviços e componentes do Hadoop instalados. Se o script esperar uma versão específica de um serviço ou componente, só deve utilizar o script com a versão do HDInsight que inclui os componentes necessários. Pode encontrar informações sobre versões de componentes incluídas no HDInsight com o documento de controlo de versões de componentes do HDInsight .
Verificar a versão do sistema operativo
Diferentes versões do HDInsight dependem de versões específicas do Ubuntu. Podem existir diferenças entre as versões do SO que tem de verificar no script. Por exemplo, poderá ter de instalar um binário associado à versão do Ubuntu.
Para verificar a versão do SO, utilize lsb_release
. Por exemplo, o seguinte script demonstra como referenciar um ficheiro tar específico consoante a 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
Direcionar a versão do sistema operativo
O HDInsight baseia-se na distribuição do Ubuntu Linux. Diferentes versões do HDInsight dependem de diferentes versões do Ubuntu, que podem alterar o comportamento do script. Por exemplo, o HDInsight 3.4 e anterior baseiam-se em versões do Ubuntu que utilizam o Upstart. As versões 3.5 e superiores baseiam-se no Ubuntu 16.04, que utiliza Systemd. Systemd e Upstart dependem de comandos diferentes, pelo que o script deve ser escrito para trabalhar com ambos.
Outra diferença importante entre o HDInsight 3.4 e 3.5 é que JAVA_HOME
agora aponta para Java 8. O código seguinte demonstra como determinar se o script está em execução 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
Pode encontrar o script completo que contém estes fragmentos em https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.
Para obter a versão do Ubuntu que é utilizada pelo HDInsight, veja o documento de versão do componente do HDInsight .
Para compreender as diferenças entre Systemd e Upstart, veja Systemd for Upstart users (Systemd for Upstart users).
Fornecer ligações estáveis para recursos de script
O script e os recursos associados têm de permanecer disponíveis ao longo da duração do cluster. Estes recursos são necessários se forem adicionados novos nós ao cluster durante as operações de dimensionamento.
A melhor prática é transferir e arquivar tudo numa conta de Armazenamento do Azure na sua subscrição.
Importante
A conta de armazenamento utilizada tem de ser a conta de armazenamento predefinida para o cluster ou um contentor público só de leitura em qualquer outra conta de armazenamento.
Por exemplo, os exemplos fornecidos pela Microsoft são armazenados na https://hdiconfigactions.blob.core.windows.net/
conta de armazenamento. Esta localização é um contentor público só de leitura mantido pela equipa do HDInsight.
Utilizar recursos pré-compilados
Para reduzir o tempo necessário para executar o script, evite operações que compilam recursos a partir do código fonte. Por exemplo, pré-compile recursos e armazene-os num blob de conta de Armazenamento do Azure no mesmo datacenter que o HDInsight.
Certifique-se de que o script de personalização do cluster é idempotente
Os scripts têm de ser idempotentes. Se o script for executado várias vezes, deverá devolver sempre o cluster ao mesmo estado.
Por exemplo, um script que modifica os ficheiros de configuração não deve adicionar entradas duplicadas se for executado várias vezes.
Garantir a elevada disponibilidade da arquitetura do cluster
Os clusters do HDInsight baseados em Linux fornecem dois nós principais que estão ativos no 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 foram concebidos para efetuar a ativação pós-falha entre os dois nós principais, conforme necessário. Esta funcionalidade não é expandida para componentes personalizados instalados através de ações de script. Se precisar de elevada disponibilidade para componentes personalizados, tem de implementar o seu próprio mecanismo de ativação pós-falha.
Configurar os componentes personalizados para utilizar o armazenamento de Blobs do Azure
Os componentes instalados no cluster podem ter uma configuração predefinida que utiliza o armazenamento do Sistema de Ficheiros Distribuído do Apache Hadoop (HDFS). O HDInsight utiliza o Armazenamento do Azure ou Data Lake Storage como o armazenamento predefinido. Ambos fornecem um sistema de ficheiros compatível com HDFS que persiste nos dados, mesmo que o cluster seja eliminado. Poderá ter de configurar os componentes instalados para utilizar o WASB ou o ADL em vez do HDFS.
Para a maioria das operações, não precisa de especificar o sistema de ficheiros. Por exemplo, o seguinte copia o ficheiro hadoop-common.jar do sistema de ficheiros local para o armazenamento de clusters:
hdfs dfs -put /usr/hdp/current/hadoop-client/hadoop-common.jar /example/jars/
Neste exemplo, o hdfs
comando utiliza de forma transparente o armazenamento de clusters predefinido. Para algumas operações, poderá ter de 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 o Armazenamento do Azure.
Escrever informações para STDOUT e STDERR
O HDInsight regista a saída do script que é escrita em STDOUT e STDERR. Pode ver estas informações com a IU da Web do Ambari.
Nota
O Apache Ambari só está disponível se o cluster for criado com êxito. Se utilizar uma ação de script durante a criação do cluster e a criação falhar, veja Resolver problemas de ações de script para outras formas de aceder a informações registadas.
A maioria dos utilitários e pacotes de instalação já escreve informações em STDOUT e STDERR. No entanto, poderá querer adicionar registos adicionais. Para enviar texto para STDOUT, utilize echo
. Por exemplo:
echo "Getting ready to install Foo"
Por predefinição, echo
envia a cadeia para STDOUT. Para direcioná-lo para STDERR, adicione >&2
antes echo
de . Por exemplo:
>&2 echo "An error occurred installing Foo"
Em vez disso, redireciona as informações escritas 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 a visualização de informações registadas por ações de script, veja Resolver problemas de ações de scripts.
Guardar ficheiros como ASCII com terminações de linha LF
Os scripts bash devem ser armazenados como formato ASCII, com linhas terminadas por LF. Os ficheiros armazenados como UTF-8 ou que utilizem CRLF como terminação da linha podem falhar com o seguinte erro:
$'\r': command not found
line 1: #!/usr/bin/env: No such file or directory
Utilizar a lógica de repetição para recuperar de erros transitórios
Ao transferir ficheiros, instalar pacotes com apt-get ou outras ações que transmitem dados através da Internet, a ação pode falhar devido a erros transitórios de rede. Por exemplo, o recurso remoto com o qual está a comunicar pode estar em processo de ativação pós-falha para um nó de cópia de segurança.
Para tornar o script resiliente a erros transitórios, pode implementar a lógica de repetição. A função seguinte demonstra como implementar a lógica de repetição. Volta a tentar 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 seguintes demonstram como utilizar esta 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 pode utilizar ao escrever scripts personalizados. Estes métodos estão contidos no https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh script. Utilize o seguinte para transferi-los e utilizá-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 seguintes programadores de ajuda disponíveis para utilização no script:
Utilização do programa auxiliar | Descrição |
---|---|
download_file SOURCEURL DESTFILEPATH [OVERWRITE] |
Transfere um ficheiro do URI de origem para o caminho de ficheiro especificado. Por predefinição, não substitui um ficheiro existente. |
untar_file TARFILE DESTDIR |
Extrai um ficheiro tar (com -xf ) para o diretório de destino. |
test_is_headnode |
Se o script tiver sido executado num nó principal do cluster, devolve 1; caso contrário, 0. |
test_is_datanode |
Se o nó atual for um nó de dados (trabalho), devolva um 1; caso contrário, 0. |
test_is_first_datanode |
Se o nó atual for o primeiro nó de dados (worker) (denominado workernode0) devolver um 1; caso contrário, 0. |
get_headnodes |
Devolva o nome de domínio completamente qualificado dos nós principais no cluster. Os nomes são delimitados por vírgulas. É devolvida uma cadeia vazia com o erro . |
get_primary_headnode |
Obtém o nome de domínio completamente qualificado do nó principal principal. É devolvida uma cadeia vazia com o erro . |
get_secondary_headnode |
Obtém o nome de domínio completamente qualificado do nó principal secundário. É devolvida uma cadeia vazia com o erro . |
get_primary_headnode_number |
Obtém o sufixo numérico do nó principal primário. É devolvida uma cadeia vazia com o erro . |
get_secondary_headnode_number |
Obtém o sufixo numérico do nó principal secundário. É devolvida uma cadeia vazia com o erro . |
Padrões de utilização comuns
Esta secção fornece orientações sobre como implementar alguns dos padrões de utilização comuns que pode encontrar ao escrever o seu próprio script personalizado.
Transmitir parâmetros para um script
Em alguns casos, o script pode exigir parâmetros. Por exemplo, poderá precisar da palavra-passe de administrador do cluster ao utilizar a API REST do Ambari.
Os parâmetros transmitidos 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 sucessivamente. $0
contém o nome do próprio script.
Os valores transmitidos ao script como parâmetros devem ser colocados entre plicas ('). Ao fazê-lo, garante que o valor transmitido é tratado como um literal.
Definir variáveis de ambiente
A definição de uma variável de ambiente é efetuada pela seguinte instrução:
VARIABLENAME=value
No exemplo anterior, VARIABLENAME
é o nome da variável . Para aceder à variável, utilize $VARIABLENAME
. Por exemplo, para atribuir um valor fornecido por um parâmetro posicional como uma variável de ambiente denominada PASSWORD, utilizaria a seguinte instrução:
PASSWORD=$1
Em seguida, o acesso subsequente às informações poderia utilizar $PASSWORD
.
As variáveis de ambiente definidas no script só existem no âmbito do script. Em alguns casos, poderá ter de adicionar variáveis de ambiente ao nível do sistema que irão persistir após a conclusão do script. Para adicionar variáveis de ambiente ao nível do sistema, adicione a variável a /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 localizações onde os scripts personalizados estão armazenados
Os scripts utilizados para personalizar um cluster têm de ser armazenados numa das seguintes localizações:
Uma conta de Armazenamento do Azure associada ao cluster.
Uma conta de armazenamento adicional associada ao cluster.
Um URI legível publicamente. Por exemplo, um URL para dados armazenados no OneDrive, Dropbox ou outro serviço de alojamento de ficheiros.
Uma conta Azure Data Lake Storage associada ao cluster do HDInsight. Para obter mais informações sobre como utilizar Azure Data Lake Storage com o HDInsight, veja Início Rápido: Configurar clusters no HDInsight.
Nota
O principal de serviço que o HDInsight utiliza para aceder Data Lake Storage tem de ter acesso de leitura ao script.
Os recursos utilizados pelo script também têm de estar publicamente disponíveis.
Armazenar os ficheiros numa conta de Armazenamento do Azure ou Azure Data Lake Storage fornece acesso rápido, tal como na rede do Azure.
Nota
O formato URI utilizado para referenciar o script difere consoante o serviço que está a ser utilizado. Para contas de armazenamento associadas ao cluster do HDInsight, utilize wasb://
ou wasbs://
. Para URIs legíveis publicamente, utilize http://
ou https://
. Para Data Lake Storage, utilize adl://
.
Lista de verificação para implementar uma ação de script
Eis os passos a seguir ao preparar a implementação de um script:
- Coloque os ficheiros que contêm os scripts personalizados num local acessível pelos nós de cluster durante a implementação. Por exemplo, o armazenamento predefinido para o cluster. Os ficheiros também podem ser armazenados em serviços de alojamento legíveis publicamente.
- Verifique se o script é idempotente. Fazê-lo permite que o script seja executado várias vezes no mesmo nó.
- Utilize um diretório de ficheiros /tmp temporário para manter os ficheiros transferidos utilizados pelos scripts e, em seguida, limpe-os após a execução dos scripts.
- Se as definições ao nível do SO ou os ficheiros de configuração do serviço Hadoop forem alterados, poderá querer reiniciar os serviços do HDInsight.
Como executar uma ação de script
Pode utilizar ações de script para personalizar clusters do HDInsight com 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 utilizar cada método, veja Como utilizar a ação de script.
Exemplos de scripts personalizados
A Microsoft fornece scripts de exemplo para instalar componentes num cluster do HDInsight. Veja Instalar e utilizar o Hue em clusters do HDInsight como uma ação de script de exemplo.
Resolução de problemas
Seguem-se erros que pode encontrar ao utilizar scripts que desenvolveu:
Erro: $'\r': command not found
. Por vezes, seguido de syntax error: unexpected end of file
.
Causa: este erro é causado quando as linhas num script terminam com CRLF. Os sistemas Unix esperam apenas LF à medida que a linha termina.
Este problema ocorre com mais frequência quando o script é criado num ambiente do Windows, uma vez que CRLF é uma linha comum que termina para muitos editores de texto no Windows.
Resolução: se for uma opção no seu editor de texto, selecione Formato Unix ou LF para a linha que termina. Também pode utilizar os seguintes comandos num sistema Unix para alterar o CRLF para um LF:
Nota
Os seguintes comandos são aproximadamente equivalentes, uma vez que devem alterar as terminações da linha CRLF para LF. Selecione um com base nos utilitários disponíveis no seu sistema.
Comando | Notas |
---|---|
unix2dos -b INFILE |
O ficheiro original é efetuado uma cópia de segurança com um . Extensão BAK |
tr -d '\r' < INFILE > OUTFILE |
OUTFILE contém uma versão com apenas finais LF |
perl -pi -e 's/\r\n/\n/g' INFILE |
Modifica diretamente o ficheiro |
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE |
OUTFILE contém uma versão com apenas finais LF. |
Erro: line 1: #!/usr/bin/env: No such file or directory
.
Causa: este erro ocorre quando o script foi guardado como UTF-8 com uma Marca de Encomenda byte (BOM).
Resolução: guarde o ficheiro como ASCII ou como UTF-8 sem um BOM. Também pode utilizar o seguinte comando num sistema Linux ou Unix para criar um ficheiro sem o BOM:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
Substitua INFILE
pelo ficheiro que contém o BOM. OUTFILE
deve ser um novo nome de ficheiro, que contém o script sem o BOM.
Passos seguintes
- Saiba como Personalizar clusters do HDInsight com a ação de script
- Utilize a referência do SDK .NET do HDInsight para saber mais sobre como criar aplicações .NET que gerem o HDInsight
- Utilize a API REST do HDInsight para saber como utilizar o REST para realizar ações de gestão em clusters do HDInsight.