تطوير إجراء البرنامج النصي مع HDInsight

تعرف على كيفية تخصيص نظام مجموعة HDInsight باستخدام برامج Bash النصية. إجراءات البرنامج النصي هي طريقة لتخصيص HDInsight أثناء إنشاء نظام المجموعة أو بعده.

تعريف إجراءات البرنامج النصي

إجراءات البرنامج النصي هي البرامج النصية Bash التي تُشغلها Azure على عُقد نظام المجموعة لإجراء تغييرات التكوين أو تثبيت البرامج. يتم تنفيذ إجراء البرنامج نصي كجذر، ويوفر حقوق الوصول الكامل إلى عُقد نظام المجموعة.

يمكن تطبيق إجراءات البرنامج النصي من خلال الطرق التالية:

استخدم هذا الأسلوب لتطبيق برنامج نصي... أثناء إنشاء نظام المجموعة... على نظام مجموعة قيد التشغيل...
مدخل Azure
Azure PowerShell
Azure Classic CLI  
HDInsight .NET SDK
قالب Azure Resource Manager  

للاطلاع على مزيد من المعلومات حول استخدام هذه الأساليب لتطبيق إجراءات البرامج النصية، راجع المستند تخصيص أنظمة مجموعات HDInsight باستخدام إجراءات النصوص البرمجية.

أفضل الممارسات لتطوير البرامج النصية

عند تطوير برنامج نصي مخصص لنظام مجموعة HDInsight، هناك العديد من أفضل الممارسات التي يجب وضعها في الاعتبار:

هام

يجب إكمال إجراءات البرنامج النصي في غضون 60 دقيقة وإلا ستفشل العملية. أثناء توفير العُقدة، يتم تشغيل البرنامج النصي بشكل متزامن مع عمليات الإعداد والتكوين الأخرى. قد يتسبب التنافس على الموارد مثل وقت CPU أو النطاق الترددي للشبكة في أن يستغرق البرنامج النصي وقتاً أطول للانتهاء مما هو عليه في بيئة التطوير لديك.

استهداف إصدار Apache Hadoop

إصدارات مختلفة من HDInsight لديها إصدارات مختلفة من خدمات Hadoop والمكونات المثبتة. إذا كان البرنامج النصي الخاص بك يتوقع إصداراً محدداً من خدمة أو مكون، يجب عليك فقط استخدام البرنامج النصي مع إصدار HDInsight الذي يتضمن المكونات المطلوبة. يمكنك العثور على معلومات حول إصدارات المكوّن المتوفرة مع HDInsight باستخدام مستند تعيين إصدار مكوّن HDInsight.

التحقق من إصدار نظام تشغيل

تعتمد إصدارات مختلفة من HDInsight على إصدارات محددة من Ubuntu. قد تكون هناك اختلافات بين إصدارات نظام التشغيل التي يجب التحقق من وجودها في البرنامج النصي الخاص بك. على سبيل المثال، قد تحتاج إلى تثبيت ثنائي يكون مرتبطاً بإصدار Ubuntu.

للتحقق من إصدار نظام التشغيل، استخدم lsb_release. على سبيل المثال، يوضح البرنامج النصي التالي كيفية الرجوع إلى ملف tar محدد استناداً إلى إصدار نظام التشغيل:

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

استهداف إصدار نظام التشغيل

يستند HDInsight إلى توزيع Ubuntu Linux. تعتمد إصدارات مختلفة من HDInsight على إصدارات مختلفة من Ubuntu، والذي من شأنه أن يُغير سلوك برنامجك النصي. على سبيل المثال، يستند إصدار 3.4 من HDInsight والإصدارات السابقة إلى إصدارات Ubuntu التي تستخدم Upstart. تستند إصدارات 3.5 والأحدث إلى Ubuntu 16.04، والذي يستخدم Systemd. يعتمد كل من Systemd وUpstart على أوامر مختلفة، لذا يجب كتابة برنامجك النصي للعمل مع كليهما.

وهناك اختلاف آخر مهم بين HDInsight 3.4 و3.5 وهو أن JAVA_HOME يشير الآن إلى Java 8. توضح التعليمات البرمجية التالية كيفية تحديد ما إذا كان البرنامج النصي يتم تشغيله على Ubuntu 14 أم 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

يمكنك العثور على البرنامج النصي الكامل الذي يحتوي على هذه القصاصات البرمجية في https://hdiconfigactions.blob.core.windows.net/linuxhueconfigactionv02/install-hue-uber-v02.sh.

للحصول على إصدار Ubuntu الذي يستخدمه HDInsight، راجع مستند إصدار مكوّن HDInsight.

لفهم الاختلافات بين Systemd وUpstart، راجع Systemd لمستخدمي Upstart.

توفير ارتباطات ثابتة لموارد البرنامج النصي

يجب أن يظل البرنامج النصي والموارد المقترنة متوفرة طوال مدة بقاء نظام المجموعة. تُعد هذه الموارد مطلوبة إذا تمت إضافة عُقد جديدة إلى نظام المجموعة أثناء عمليات التحجيم.

إن أفضل الممارسات هي تنزيل كل شيء وأرشفته في حساب تخزين Azure باشتراكك.

هام

يجب أن يكون حساب التخزين المستخدم هو حساب التخزين الافتراضي لنظام المجموعة أو حاوية عامة للقراءة فقط على أي حساب تخزين آخر.

على سبيل المثال، يتم تخزين النماذج التي توفرها Microsoft في حساب التخزين https://hdiconfigactions.blob.core.windows.net/. يُعد هذا الموقع هو حاوية عامة للقراءة فقط يحتفظ بها فريق HDInsight.

استخدام موارد تم تحويلها برمجياً

لتقليل الوقت الذي يستغرقه تشغيل البرنامج النصي، تجنب العمليات التي تقوم بتحويل الموارد برمجياً من التعليمات البرمجية المصدر. على سبيل المثال، قم بالتحويل البرمجي المسبق للموارد وتخزينها في كائن ثنائي كبير الحجم لحساب تخزين Azure في نفس مركز البيانات مثل HDInsight.

التأكد من أن يكون البرنامج النصي لتخصيص نظام المجموعة لا متغير

يجب أن تكون البرامج النصية لا متغيرة. إذا كان البرنامج النصي يعمل عدة مرات، فإنه يجب أن يقوم بإرجاع نظام المجموعة إلى نفس الحالة في كل مرة.

على سبيل المثال، لا يجب أن يقوم البرنامج النصي الذي يُعدل ملفات التكوين بإضافة إدخالات مكررة إذا تم التشغيل عدة مرات.

ضمان قابلية الوصول العالية لبنية نظام المجموعة

توفر أنظمة مجموعات HDInsight المستندة إلى نظام Linux عقدتين رأسيتين نشطتين داخل نظام المجموعة ويتم تشغيل إجراءات البرنامج النصي على العقدتين. إذا كانت المكونات التي تقوم بتثبيتها تتوقع عقدة رأس واحدة فقط، فلا تقم بتثبيت المكونات على كلا العقدتين الرأسيتين.

هام

تم تصميم الخدمات المقدمة كجزء من HDInsight لتجاوز الفشل بين العقدتين الرأسيتين حسب الحاجة. لم يتم توسيع هذه الوظيفة للمكونات المخصصة المثبتة من خلال إجراءات البرنامج النصي. إذا كنت بحاجة إلى قابلية وصول عالية للمكونات المخصصة، يجب تطبيق آلية تجاوز الفشل الخاصة بك.

تكوين المكونات المخصصة لاستخدام تخزين Azure Blob

قد تحتوي المكونات التي تقوم بتثبيتها على نظام المجموعة على تكوين افتراضي يستخدم تخزين نظام الملفات الموزعة لدى Apache Hadoop (HDFS). يستخدم HDInsight إما تخزين Azure أو تخزين Data Lake Storage كموقع تخزين افتراضي. يوفر كلاهما نظام ملفات متوافق مع HDFS يحتفظ بالبيانات حتى إذا تم حذف نظام المجموعة. قد تحتاج إلى تكوين المكونات التي تقوم بتثبيتها لاستخدام WASB أو ADL بدلاً من HDFS.

بالنسبة لمعظم العمليات، لا تحتاج إلى تحديد نظام الملفات. على سبيل المثال، يقوم ما يلي بنسخ ملف hadoop-common.jar من نظام الملفات المحلي لتخزين نظام المجموعة:

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

في هذا المثال، يستخدم الأمر hdfs بشفافية تخزين نظام المجموعة الافتراضي. بالنسبة لبعض العمليات، قد تحتاج إلى تحديد معرف موارد منتظم. على سبيل المثال، adl:///example/jars لـ Azure Data Lake Storage Gen1، وabfs:///example/jars لـ Data Lake Storage Gen2 أو wasb:///example/jars لتخزين Azure.

كتابة المعلومات إلى STDOUT وSTDERR

يقوم HDInsight بتسجيل إخراج البرنامج النصي الذي يتم كتابته إلى STDOUT وSTDERR. يمكنك عرض هذه المعلومات باستخدام واجهة مستخدم الويب لـ Ambari.

ملاحظة

يتوفر Apache Ambari فقط إذا تم إنشاء نظام المجموعة بنجاح. إذا كنت تستخدم إجراء برنامج نصي أثناء إنشاء نظام المجموعة، وفشلت عملية الإنشاء، فراجع استكشاف أخطاء إجراءات البرنامج النصي وإصلاحها لمعرفة طرق أخرى للوصول إلى المعلومات المسجلة.

تقوم معظم الأدوات المساعدة وحزم التثبيت بكتابة المعلومات بالفعل إلى STDOUT وSTDERR، ولكن قد ترغب في إضافة تسجيل آخر. لإرسال نص إلى STDOUT، استخدم echo. على سبيل المثال:

echo "Getting ready to install Foo"

بشكل افتراضي، يرسل echo السلسلة إلى STDOUT. لتوجيهه إلى STDERR، أضف >&2 قبل echo. على سبيل المثال:

>&2 echo "An error occurred installing Foo"

هذا يعيد توجيه المعلومات المكتوبة إلى STDOUT إلى STDERR (2) بدلاً من ذلك. لمزيد من المعلومات حول إعادة توجيه IO، راجع https://www.tldp.org/LDP/abs/html/io-redirection.html.

لمزيد من المعلومات حول عرض المعلومات المسجلة بواسطة إجراءات البرنامج النصي، راجع استكشاف أخطاء إجراءات البرنامج النصي وإصلاحها.

حفظ الملفات بتنسيق ASCII مع نهايات سطر LF

يجب تخزين البرامج النصية Bash بتنسيق ASCII، مع وضع LF بنهاية الأسطر. قد تفشل عملية الملفات المخزنة بتنسيق UTF-8، أو تستخدم CRLF كنهاية السطر مع ظهور الخطأ التالي:

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

استخدام منطق إعادة المحاولة للاسترداد من الأخطاء المؤقتة

عند تنزيل الملفات أو تثبيت الحزم باستخدام apt-get، أو الإجراءات الأخرى التي ترسل البيانات عبر الإنترنت، قد يفشل الإجراء بسبب أخطاء الشبكات المؤقتة. على سبيل المثال، قد يكون المورد البعيد الذي تتواصل معه يقوم بعملية تجاوز الفشل لعقدة النسخ الاحتياطي.

لكي تجعل البرنامج النصي الخاص بك يتعامل مع الأخطاء المؤقتة بمرونة، يمكنك تطبيق منطق إعادة المحاولة. توضح الدالة التالية كيفية تطبيق منطق إعادة المحاولة. فإنها أجرت إعادة محاولة العملية ثلاث مرات قبل فشل العملية.

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

توضح الأمثلة التالية كيفية استخدام هذه الدالة.

retry ls -ltr foo

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

أساليب المساعد للبرامج النصية المخصصة

تُعد أساليب مساعد إجراء البرنامج النصي هي الأدوات المساعدة التي يمكنك استخدامها أثناء كتابة البرامج النصية المخصصة. يتم تصمين هذه الأساليب في البرنامج النصي https://hdiconfigactions.blob.core.windows.net/linuxconfigactionmodulev01/HDInsightUtilities-v01.sh. استخدم ما يلي لتنزيلها واستخدامها كجزء من البرنامج النصي لديك:

# 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

تتوفر عناصر المساعد التالية للاستخدام في البرنامج النصي الخاص بك:

استخدام المساعد الوصف
download_file SOURCEURL DESTFILEPATH [OVERWRITE] تنزيل ملف من URI المصدر إلى مسار الملف المحدد. بشكل افتراضي، لا يقوم بالكتابة فوق ملف موجود.
untar_file TARFILE DESTDIR استخراج ملف tar (باستخدام -xf) إلى الدليل الوجهة.
test_is_headnode إذا كان البرنامج النصي يعمل على عقدة رأس نظام المجموعة، فقم بإرجاع 1؛ خلاف ذلك، 0.
test_is_datanode إذا كانت العقدة الحالية هي عقدة بيانات (عاملة)، فقم بإرجاع 1؛ خلاف ذلك، 0.
test_is_first_datanode إذا كانت العقدة الحالية هي عقدة البيانات (العاملة) الأولى (باسم workernode0)، فقم بإرجاع 1؛ خلاف ذلك، 0.
get_headnodes إرجاع اسم المجال المؤهل بالكامل من العقد الرئيسية في مجموعة النظام. يتم فصل الأسماء بفاصلة. يتم إرجاع سلسلة فارغة عند الخطأ.
get_primary_headnode يحصل على اسم المجال المؤهل بالكامل من عقدة الرأس الأساسية. يتم إرجاع سلسلة فارغة عند الخطأ.
get_secondary_headnode يحصل على اسم المجال المؤهل بالكامل من عقدة الرأس الثانوية. يتم إرجاع سلسلة فارغة عند الخطأ.
get_primary_headnode_number يحصل على لاحقة رقمية من العقد الرئيسية الأساسية. يتم إرجاع سلسلة فارغة عند الخطأ.
get_secondary_headnode_number يحصل على لاحقة رقمية من العقد الرئيسية الثانوية. يتم إرجاع سلسلة فارغة عند الخطأ.

أنماط الاستخدام الشائعة

يوفر هذا القسم إرشادات حول تطبيق بعض أنماط الاستخدام الشائعة التي قد واجهتك أثناء كتابة البرنامج النصي المخصص الخاص بك.

تمرير المعلمات إلى برنامج نصي

في بعض الحالات، قد يتطلب البرنامج النصي المعلمات. على سبيل المثال، قد تحتاج كلمة مرور المسؤول لنظام المجموعة عند استخدام واجهة برمجة تطبيقات Ambari REST.

تُعرف المعلمات التي تم تمريرها إلى البرنامج النصي باسم المعلمات الموضعية، ويتم تعيينها إلى $1 المعلمة الأولى، $2 للمعلمة الثانية، وهكذا. $0 يحتوي على اسم البرنامج النصي نفسه.

يجب أن تكون القيم التي تم تمريرها إلى البرنامج النصي كمعلمات محاطة بعلامات اقتباس مفردة ('). يضمن القيام بذلك أن القيمة التي تم تمريرها يتم التعامل معها كقيمة حرفية.

إعداد متغيرات البيئة

يتم تنفيذ متغير البيئة بواسطة العبارة التالية:

VARIABLENAME=value

في المثال السابق، VARIABLENAME هو اسم المتغير. للوصول إلى المتغير، استخدم $VARIABLENAME. على سبيل المثال، لتعيين قيمة مقدمة من قبل معلمة موضعية كمتغير بيئة المسمى باسم PASSWORD، يمكنك استخدام العبارة التالية:

PASSWORD=$1

ويمكن بعد ذلك أن يستخدم الوصول اللاحق إلى المعلومات $PASSWORD.

توجد متغيرات البيئة التي تم تعيينها داخل البرنامج النصي ضمن نطاق البرنامج النصي فقط. في بعض الحالات، قد تحتاج إلى إضافة متغيرات البيئة على مستوى النظام الذي سيستمر بعد انتهاء البرنامج النصي. لإضافة متغيرات البيئة على مستوى النظام، أضف المتغير إلى /etc/environment. على سبيل المثال، تضيف العبارة التالية HADOOP_CONF_DIR:

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

الوصول إلى المواقع التي يتم فيها تخزين البرامج النصية المخصصة

يجب تخزين البرامج النصية المستخدمة لتخصيص نظام مجموعة في أحد المواقع التالية:

  • حساب تخزين Azure المقترن بنظام المجموعة.

  • حساب تخزين إضافي المقترن بنظام المجموعة.

  • URI قابل للقراءة بشكل عام. على سبيل المثال، عنوان URL للبيانات المخزنة على OneDrive، أو Dropbox، أو خدمة استضافة ملفات أخرى.

  • حساب تخزين Azure Data Lake Storage المقترن بنظام مجموعة HDInsight. لمزيد من المعلومات حول استخدام Azure Data Lake Storage مع HDInsight، راجع التشغيل السريع: إعداد نظام المجموعات في HDInsight.

    ملاحظة

    يجب أن يكون للخدمة الرئيسية التي يستخدمها HDInsight للوصول إلى Data Lake Storage حق الوصول للقراءة إلى البرنامج النصي.

يجب أن تكون الموارد المستخدمة من قِبل البرنامج النصي متاحة للجمهور أيضاً.

يوفر تخزين الملفات في حساب تخزين Azure أو Azure Data Lake Storage الوصول السريع، إذ إن كليهما داخل شبكة Azure.

ملاحظة

يختلف تنسيق URI المستخدم للإشارة إلى البرنامج النصي حسب الخدمة المستخدمة. لحسابات التخزين المقترنة مع نظام مجموعة HDInsight، استخدم wasb:// أو wasbs://. لمعرف URI القابل للقراءة بشكل عام، استخدم http:// أو https://. لتخزين Data Lake Storage، استخدم adl://.

قائمة اختيار لنشر إجراء برنامج نصي

فيما يلي الخطوات التي يتم اتخاذها عند التحضير لنشر برنامج نصي:

  • وضع الملفات التي تحتوي على البرامج النصية المخصصة في مكان يمكن الوصول إليه بواسطة عُقد نظام المجموعة أثناء النشر. على سبيل المثال، التخزين الافتراضي لنظام المجموعة. يمكن أيضاً تخزين الملفات في خدمات استضافة قابلة للقراءة بشكل عام.
  • تحقق من أن يكون البرنامج النصي لا متغير. يسمح القيام بذلك بتنفيذ البرنامج النصي عدة مرات على العقدة نفسها.
  • استخدام دليل ملف مؤقت /tmp للاحتفاظ بالملفات التي تم تنزيلها والمستخدمة من قِبل البرامج النصية ثم تنظيفها بعد تنفيذ البرامج النصية.
  • إذا تم تغيير إعدادات مستوى نظام التشغيل أو ملفات تكوين خدمة Hadoop، فقد تحتاج إلى إعادة تشغيل خدمات HDInsight.

كيفية تشغيل إجراء برنامج نصي

يمكنك استخدام إجراءات البرنامج النصي لتخصيص أنظمة مجموعات HDInsight باستخدام الأساليب التالية:

  • مدخل Azure
  • Azure PowerShell
  • قوالب Azure Resource Manager
  • HDInsight .NET SDK.

لمزيد من المعلومات حول استخدام كل أسلوب، راجع كيفية استخدام إجراء البرنامج النصي.

نماذج البرامج النصية المخصصة

توفر Microsoft نماذج من البرامج النصية لتثبيت المكونات على نظام مجموعة HDInsight. راجع تثبيت Hue واستخدامه على أنظمة مجموعات HDInsight كمثال على إجراء البرنامج النصي.

استكشاف الأخطاء وإصلاحها

فيما يلي الأخطاء التي قد تصادفها عند استخدام البرامج النصية التي طورتها:

خطأ: $'\r': command not found. في بعض الأحيان يليه syntax error: unexpected end of file.

السبب: يحدث هذا الخطأ عند انتهاء الأسطر في برنامج نصي بـ CRLF. تتوقع أنظمة Unix فقط LF مع نهاية السطر.

تحدث هذه المشكلة غالباً عند إنشاء البرنامج النصي على بيئة Windows، إذ إن CRLF هو نهاية سطر شائعة للعديد من محرري النص على نظام Windows.

الحل: إذا كان يوجد الخيار في محرر النص، فحدد تنسيق Unix أو LF لنهاية السطر. يمكنك أيضاً استخدام الأوامر التالية على نظام Unix لتغيير CRLF إلى LF:

ملاحظة

تُعد الأوامر التالية مكافئة تقريباً إذ إنها يجب أن تغير نهايات سطر CRLF إلى LF. حدد واحداً استناداً إلى الأدوات المساعدة المتوفرة على نظامك.

الأمر ملاحظات
unix2dos -b INFILE يتم إجراء النسخ الاحتياطي من الملف الأصلي مع ملحق .BAK
tr -d '\r' < INFILE > OUTFILE يحتوي OUTFILE على إصدار بنهايات LF فقط
perl -pi -e 's/\r\n/\n/g' INFILE تعديل الملف مباشرةً
sed 's/$'"/`echo \\\r`/" INFILE > OUTFILE يحتوي OUTFILE على إصدار بنهايات LF فقط.

خطأ: line 1: #!/usr/bin/env: No such file or directory.

السبب: يحدث هذا الخطأ عند حفظ البرنامج النصي بتنسيق UTF-8 بعلامة ترتيب وحدات البايت (BOM).

الحل: حفظ الملف إما بتنسيق ASCII أو UTF-8 دون علامة ترتيب وحدات البايت. يمكنك أيضاً استخدام الأمر التالي على نظام Linux أو Unix لإنشاء ملف دون علامة ترتيب وحدات البايت:

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

استبدل INFILE بالملف الذي يحتوي على علامة ترتيب وحدات البايت. OUTFILE يجب أن يكون اسم ملف جديد، والذي يحتوي على البرنامج النصي دون علامة ترتيب وحدات البايت.

الخطوات التالية