Skript-actionutveckling med HDInsight

Lär dig hur du kan anpassa ditt HDInsight-kluster med Bash-skript. Skriptåtgärder är ett sätt att anpassa HDInsight under eller efter klusterskapandet.

Vad är skriptåtgärder

Skriptåtgärder är Bash-skript som Azure kör på klusternoder för att göra konfigurationsändringar eller installera programvara. En skriptåtgärd utförs som root och ger full åtkomst till klusternoderna.

Skriptåtgärder kan tillämpas med följande metoder:

Använd den här metoden för att applicera ett skript... När klustret skapas... I ett körande kluster...
Azure portal ✓ ✓
Azure PowerShell ✓ ✓
Azure Classic CLI   ✓
HDInsight .NET SDK ✓ ✓
Azure Resource Manager-mall ✓  

För mer information om hur man använder dessa metoder för att tillämpa skriptåtgärder, se Anpassa HDInsight-kluster med skriptåtgärder.

Bästa praxis för manusutveckling

När du utvecklar ett anpassat skript för ett HDInsight-kluster finns det flera bästa praxis att ha i åtanke:

Important

Skriptåtgärder måste slutföras inom 60 minuter, annars misslyckas processen. Under nodprovisionering körs skriptet samtidigt med andra installations- och konfigurationsprocesser. Konkurrens om resurser som CPU-tid eller nätverksbandbredd kan göra att skriptet tar längre tid att slutföra än i din utvecklingsmiljö.

Sikta på Apache Hadoop-versionen

Olika versioner av HDInsight har olika versioner av Hadoop-tjänster och komponenter installerade. Om ditt skript förväntar sig en specifik version av en tjänst eller komponent, bör du endast använda skriptet med den version av HDInsight som inkluderar de nödvändiga komponenterna. Du kan hitta information om komponentversioner som ingår i HDInsight i dokumentet HDInsight component versioning.

Kontroll av operativsystemets version

Olika versioner av HDInsight bygger på specifika versioner av Ubuntu. Det kan finnas skillnader mellan OS-versioner som du måste kontrollera i ditt skript. Till exempel kan du behöva installera en binär fil som är kopplad till versionen av Ubuntu.

För att kontrollera OS-versionen, använd lsb_release. Till exempel demonstrerar följande skript hur man refererar till en specifik tar-fil beroende på OS-versionen:

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

Rikta in dig på operativsystemets version

HDInsight är baserat på Ubuntu Linux-distributionen. Olika versioner av HDInsight bygger på olika versioner av Ubuntu, vilket kan förändra hur ditt skript beter sig. Till exempel är HDInsight 3.4 och tidigare baserade på Ubuntu-versioner som använder Upstart. Versioner 3.5 och senare baseras på Ubuntu 16.04, som använder Systemd. Systemd och Upstart bygger på olika kommandon, så ditt skript bör vara skrivet för att fungera med båda.

En annan viktig skillnad mellan HDInsight 3.4 och 3.5 är att JAVA_HOME nu pekar på Java 8. Följande kod visar hur man avgör om skriptet körs på Ubuntu 14 eller 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

Du kan hitta hela skriptet som innehåller dessa utdrag på https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

För den version av Ubuntu som används av HDInsight, se dokumentet HDInsight component version.

För att förstå skillnaderna mellan Systemd och Upstart, se Systemd för Upstart-användare.

Tillhandahåll stabila länkar till skriptresurser

Skriptet och tillhörande resurser måste förbli tillgängliga under hela klustrets livstid. Dessa resurser krävs om nya noder läggs till klustret under skalningsoperationer.

Bästa praxis är att ladda ner och arkivera allt i ett Azure Storage-konto i ditt abonnemang.

Important

Det lagringskonto som används måste vara standardlagringskontot för klustret eller en publik container som är skrivskyddad för läsning på något annat lagringskonto.

Till exempel lagras de exempel som tillhandahålls av Microsoft i lagringskontot https://hdiconfigactions.blob.core.windows.net/. Denna plats är en offentlig, skrivskyddad container som underhålls av HDInsight-teamet.

Använd förkompilerade resurser

För att minska tiden det tar att köra skriptet, undvik operationer som kompilerar resurser från källkod. Till exempel, förkompilera resurser och lagra dem i en blob i ett Azure Storage-konto i samma datacenter som HDInsight.

Se till att klusteranpassningsskriptet är idempotent

Skript måste vara idempotenta. Om skriptet körs flera gånger bör klustret återföras till samma tillstånd varje gång.

Om skriptet körs flera gånger borde skriptet som ändrar konfigurationsfiler inte lägga till dubbletter av poster.

Säkerställ hög tillgänglighet för klusterarkitekturen

Linux-baserade HDInsight-kluster tillhandahåller två huvudnoder som är aktiva inom klustret, och skriptåtgärder körs på båda noderna. Om komponenterna du installerar förväntar sig bara en huvudnod, installera inte komponenterna på båda huvudnoderna.

Important

Tjänster som tillhandahålls som en del av HDInsight är utformade för att kunna växla över mellan de två huvudnoderna vid behov. Denna funktionalitet gäller inte för anpassade komponenter installerade via skriptåtgärder. Om du behöver hög tillgänglighet för anpassade komponenter måste du implementera din egen failover-mekanism.

Konfigurera de anpassade komponenterna för att använda Azure Blob Storage

Komponenter som du installerar i klustret kan ha en standardkonfiguration som använder Apache Hadoop Distributed File System (HDFS) lagring. HDInsight använder antingen Azure Storage eller Data Lake Storage som standardlagring. Båda tillhandahåller ett HDFS-kompatibelt filsystem som behåller data även om klustret tas bort. Du kan behöva konfigurera de komponenter du installerar så att de använder WASB eller ADL istället för HDFS.

För de flesta operationer behöver du inte ange filsystemet. Till exempel kopierar följande filen hadoop-common.jar från det lokala filsystemet till klusterlagring:

hdfs dfs -put /usr/hdp/current/hadoop-client/hadoop-common.jar /example/jars/

I detta exempel använder kommandot hdfs transparent standardklusterlagringen. För vissa operationer kan du behöva specificera URI. Till exempel adl:///example/jars för Azure Data Lake Storage Gen1, abfs:///example/jars för Data Lake Storage Gen2 eller wasb:///example/jars för Azure Storage.

Skriv information på STDOUT och STDERR

HDInsight loggar skriptutdata som skrivs till STDOUT och STDERR. Du kan se denna information via Ambari-webbgränssnittet.

Note

Apache Ambari är endast tillgänglig om klustret har skapats framgångsrikt. Om du använder en skriptåtgärd under klusterskapandet och skapandet misslyckas, se Felsökning av skriptåtgärder för andra sätt att komma åt loggad information.

De flesta verktyg och installationspaket skriver redan information till STDOUT och STDERR, men du kan vilja lägga till ytterligare loggning. För att skicka text till STDOUT, använd echo. Ett exempel:

echo "Getting ready to install Foo"

Som standard skickar echo strängen till STDOUT. För att styra den till STDERR, lägg till >&2 före echo. Ett exempel:

>&2 echo "An error occurred installing Foo"

Detta omdirigerar information skriven till STDOUT till STDERR (2) istället. För mer information om IO-omdirigering, se https://www.tldp.org/LDP/abs/html/io-redirection.html.

För mer information om att visa information som loggas av skriptåtgärder, se Felsökning av skriptåtgärder.

Spara filer som ASCII med LF-radavslutningar

Bash-skript bör lagras i ASCII-format, med rader avslutade med LF. Filer som lagras som UTF-8, eller använder CRLF som radslut, kan ge följande felmeddelande:

$'\r': command not found
line 1: #!/usr/bin/env: No such file or directory

Använd återförsökslogik för att återställa från tillfälliga fel

När du laddar ner filer, installerar paket med apt-get eller andra åtgärder som överför data över internet, kan åtgärden misslyckas på grund av tillfälliga nätverksfel. Till exempel kan den fjärrresurs du kommunicerar med vara på väg att växla över till en reservnod.

För att göra ditt skript motståndskraftigt mot tillfälliga fel kan du implementera retry-logik. Följande funktion demonstrerar hur man implementerar återförsökslogik. Den försöker utföra åtgärden tre gånger innan den misslyckas.

#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
}

Följande exempel visar hur man använder denna funktion.

retry ls -ltr foo

retry wget -O ./tmpfile.sh https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh

Hjälpmetoder för anpassade skript

Script action helper-metoder är verktyg som du kan använda när du skriver egna skript. Dessa metoder finns i https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh-skriptet. Använd följande för att ladda ner och använda dem som en del av ditt skript:

# 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

Följande hjälpmedel finns tillgängliga för användning i ditt skript:

Användning av hjälpen Description
download_file SOURCEURL DESTFILEPATH [OVERWRITE] Laddar ner en fil från käll-URI:n till den angivna filvägen. Som standard skriver den inte över en befintlig fil.
untar_file TARFILE DESTDIR Extraherar en tar-fil (med -xf) till destinationskatalogen.
test_is_headnode Om skriptet kördes på en klusterhuvudnod, returnera 1; annars 0.
test_is_datanode Om den aktuella noden är en datanod (arbetarnod), returnera en 1; annars, 0.
test_is_first_datanode Om den aktuella noden är den första datanoden (arbetarnoden) (namngiven workernode0) returnera 1; annars, 0.
get_headnodes Returnera det fullt kvalificerade domännamnet för huvudnoderna i klustret. Namnen är kommaavgränsade. En tom sträng returneras vid fel.
get_primary_headnode Hämtar det fullständigt kvalificerade domännamnet för den primära headnoden. En tom sträng returneras vid fel.
get_secondary_headnode Får det fullt kvalificerade domännamnet för den sekundära headnoden. En tom sträng returneras vid fel.
get_primary_headnode_number Hämtar det numeriska suffixet för den primära huvudnoden. En tom sträng returneras vid fel.
get_secondary_headnode_number Får det numeriska suffixet till den sekundära huvudnoden. En tom sträng returneras vid fel.

Vanliga användningsmönster

Detta avsnitt ger vägledning om hur du implementerar några av de vanliga användningsmönster som du kan stöta på när du skriver ditt eget anpassade skript.

Skicka parametrar till ett skript

I vissa fall kan ditt skript kräva parametrar. Till exempel kan du behöva administratörslösenordet för klustret när du använder Ambari REST API.

Parametrar som skickas till skriptet kallas positionsparametrar och tilldelas $1 för den första parametern, $2 för den andra och så vidare. $0 innehåller namnet på själva skriptet.

Värden som skickas till skriptet som parametrar ska omges av enkla citationstecken ('). Att göra detta säkerställer att det skickade värdet behandlas som ett literal.

Ange miljövariabler

Att sätta en miljövariabel utförs med följande sats:

VARIABLENAME=value

I föregående exempel är VARIABLENAME namnet på variabeln. För att komma åt variabeln, använd $VARIABLENAME. Till exempel, för att tilldela ett värde som ges av en positionsparameter som en miljövariabel med namnet PASSWORD, skulle du använda följande sats:

PASSWORD=$1

Efterföljande tillgång till informationen kan då använda $PASSWORD.

Miljövariabler som satts inom skriptet existerar endast inom skriptets omfattning. I vissa fall kan du behöva lägga till systemomfattande miljövariabler som kommer att finnas kvar efter att skriptet är klart. För att lägga till systemövergripande miljövariabler, lägg variabeln till /etc/environment. Till exempel lägger följande påstående till HADOOP_CONF_DIR:

echo "HADOOP_CONF_DIR=/etc/hadoop/conf" | sudo tee -a /etc/environment

Tillgång till platser där de anpassade skripten lagras

Skript som används för att anpassa ett kluster måste lagras på en av följande platser:

  • Ett Azure Storage-konto som är kopplat till klustret.

  • Ett extra lagringskonto kopplat till klustret.

  • En offentligt läsbar URI. Det kan till exempel vara en URL till data som lagras på OneDrive, Dropbox eller en annan filvärdtjänst.

  • Ett Azure Data Lake Storage-konto som är kopplat till HDInsight-klustret. För mer information om hur man använder Azure Data Lake Storage med HDInsight, se Quickstart: Set up clusters in HDInsight.

    Note

    Det tjänstens huvudnamn som HDInsight använder för att komma åt Data Lake Storage måste ha läsbehörighet till skriptet.

Resurser som används av skriptet måste också vara offentligt tillgängliga.

Att lagra filerna i ett Azure Storage-konto eller Azure Data Lake Storage ger snabb åtkomst, eftersom båda finns inom Azure-nätverket.

Note

URI-formatet som används för att referera till skriptet skiljer sig beroende på vilken tjänst som används. För lagringskonton kopplade till HDInsight-klustret, använd wasb:// eller wasbs://. För offentligt läsbara URI:er, använd http:// eller https://. För Data Lake Storage, använd adl://.

Checklista för att distribuera en skriptåtgärd

Här är stegen du bör ta när du förbereder dig för att distribuera ett skript:

  • Lägg filerna som innehåller de anpassade skripten på en plats som klusternoderna kan nå under driftsättningen. Till exempel standardlagringen för klustret. Filer kan också lagras i offentligt läsbara hostingtjänster.
  • Kontrollera att skriptet är idempotent. Genom att göra detta kan skriptet köras flera gånger på samma nod.
  • Använd en temporär filkatalog /tmp för att lagra de nedladdade filerna som används av skripten och rensa sedan upp dem efter att skripten har körts.
  • Om OS-inställningar eller konfigurationsfiler för Hadoop-tjänster ändras kan du vilja starta om HDInsight-tjänsterna.

Hur man kör en skriptåtgärd

Du kan använda skriptåtgärder för att anpassa HDInsight-kluster med följande metoder:

  • Azure portal
  • Azure PowerShell
  • Azure Resource Manager-mallar
  • HDInsight .NET SDK.

För mer information om hur man använder varje metod, se Hur man använder skriptåtgärd.

Exempel på anpassade skript

Microsoft tillhandahåller exempelskript för att installera komponenter i ett HDInsight-kluster. Se Installera och använd Hue på HDInsight-kluster som ett exempel på skriptåtgärder.

Troubleshooting

Följande är fel du kan stöta på när du använder skript du har utvecklat:

Fel: $'\r': command not found. Ibland följd av syntax error: unexpected end of file.

Orsak: Detta fel uppstår när raderna i ett skript slutar med CRLF. Unixsystem förväntar sig endast LF som radavslutning.

Detta problem uppstår oftast när skriptet är skrivet i en Windows-miljö, eftersom CRLF är en vanlig radavslutning för många textredigerare på Windows.

Lösning: Om det finns ett alternativ i din textredigerare, välj Unix-format eller LF för radavslutningen. Du kan också använda följande kommandon på ett Unix-system för att ändra CRLF till en LF:

Note

Följande kommandon är ungefär likvärdiga i det att de bör ändra CRLF-radsluten till LF. Välj en baserat på de verktyg som finns tillgängliga i ditt system.

Command Notes
unix2dos -b INFILE Den ursprungliga filen säkerhetskopieras som en fil med filändelsen .BAK
tr -d '\r' < INFILE > OUTFILE OUTFILE innehåller en version med endast LF-ändelser
perl -pi -e 's/\r\n/\n/g' INFILE Ändrar filen direkt
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE OUTFILE innehåller en version med endast radslut med LF.

Fel: line 1: #!/usr/bin/env: No such file or directory.

Orsak: Detta fel uppstår när skriptet sparades som UTF-8 med en byteordningsmarkering (BOM).

Lösning: Spara filen antingen som ASCII eller som UTF-8 utan en BOM. Du kan också använda följande kommando på ett Linux- eller Unix-system för att skapa en fil utan BOM:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE

Ersätt INFILE med filen som innehåller stycklistan. OUTFILE ska vara ett nytt filnamn som innehåller skriptet utan BOM.

Nästa steg