כדי לשלוח משימה לאשכול קיים של Managed Service for Apache Spark, אתם יכולים להשתמש בבקשה פרוגרמטית או בבקשת HTTP של ה-API jobs.submit, בכלי שורת הפקודה gcloud של Google Cloud CLI בחלון הטרמינל המקומי או ב-Cloud Shell, או במסוףGoogle Cloud שפתוח בדפדפן מקומי. אתם יכולים גם להיכנס באמצעות SSH למכונה הראשית באשכול, ואז להריץ משימה ישירות מהמכונה בלי להשתמש ב-Managed Service for Apache Spark.
משימות בו-זמניות: כשיוצרים אשכול, אפשר להגדיר את המספר המקסימלי של משימות בו-זמניות ב-Managed Service for Apache Spark באמצעות המאפיין dataproc:dataproc.scheduler.max-concurrent-jobs של האשכול. אם לא מגדירים ערך למאפיין הזה, הגבול העליון של משימות בו-זמניות מחושב לפי max((masterMemoryMb - 3584) / masterMemoryMbPerJob, 5).
הערך של masterMemoryMb נקבע לפי סוג המכונה של ה-VM הראשי.
הערך של masterMemoryMbPerJob הוא 1024 כברירת מחדל, אבל אפשר להגדיר אותו כשיוצרים את האשכול באמצעות המאפיין dataproc:dataproc.scheduler.driver-size-mb של האשכול.
איך שולחים משימה
בידוד של Classpath וקובצי JAR בהתאמה אישית: אל תעתיקו קובצי JAR בהתאמה אישית או קובצי JAR מקובצים (כמו סביבת זמן הריצה של Apache Iceberg או חבילות Google Cloud ) ישירות לספריות המערכת של האשכול, כמו /usr/lib/spark/jars/. הצבת קובצי JAR מותאמים אישית בספריות המערכת מזהמת את classpath של הסוכן של Managed Service for Apache Spark עם יחסי תלות טרנזיטיביים (כמו ספריות Guava או Hadoop) שמתנגשים עם הספריות המובנות של הסוכן. ההתנגשות הזו יכולה לגרום לשגיאות בפתרון המחלקות (כמו ClassNotFoundException או NoClassDefFoundError) כשמבצעים פעולות לניהול משימות, כמו ביטול משימה, מה שגורם לסוכן לקרוס ומשאיר את אפליקציות YARN ללא הורה.
במקום זאת, צריך להשתמש באחת מהשיטות הנתמכות הבאות:
- יחסי תלות ספציפיים למשימה: מציינים את הנתיב של קובצי ה-JAR ב-Cloud Storage כששולחים את המשימה באמצעות הדגל
--jarsב-Google Cloud CLI, השדה Jar files במסוף Google Cloud או השדהjarFileUrisב-API. Spark מפיץ את יחסי התלות לדרייבר ולמבצעים של המשימה בלי לזהם את ה-classpath של הסוכן. - יחסי תלות ברמת האשכול: מציינים את יחסי התלות במהלך יצירת האשכול באמצעות המאפיין של האשכול
spark:spark.jars: הפקודה הזו מורה ל-Managed Service for Apache Spark להגדיר את--properties="spark:spark.jars=gs://YOUR_BUCKET/jar-1.jar,gs://YOUR_BUCKET/jar-2.jar"
/etc/spark/conf/spark-defaults.conf, להפיץ באופן אוטומטי את יחסי התלות ל-driver של Spark ולנתיבי המחלקות של ה-executor לכל המשימות, ולהשאיר את הסוכן המקומי של Managed Service for Apache Spark בצומת מבודד לחלוטין.
המסוף
פותחים את הדף Submit a job של Managed Service for Apache Spark במסוף Google Cloud בדפדפן.
דוגמה למשימת Spark
כדי לשלוח משימת Spark לדוגמה, ממלאים את השדות בדף Submit a job באופן הבא:
- בקטע Select compute type for job, בוחרים באפשרות Spark on Compute Engine.
- בקטע Cluster job details, מציינים מזהה משימה (או מאשרים את מזהה ברירת המחדל) ובוחרים את ה-Cluster מרשימת האשכולות.
- בקטע Files and artifacts:
- מגדירים את סוג העבודה ל-Spark (Scala / Java) (
Spark). - בקטע Driver configuration, בוחרים באפשרות Main class ומגדירים את Main class לערך
org.apache.spark.examples.SparkPi. - מגדירים את Arguments לארגומנט היחיד
1000. - מוסיפים את
file:///usr/lib/spark/examples/jars/spark-examples.jarלקובצי Jar (או לשדהjarFileUrisשל ה-API):-
file:///מציין סכימה של Hadoop LocalFileSystem. Managed Service for Apache Spark התקין את/usr/lib/spark/examples/jars/spark-examples.jarבצומת הראשי של האשכול כשהוא יצר את האשכול. הנתיב הזה משמש רק לדוגמאות שמותקנות מראש ומסופקות על ידי Managed Service for Apache Spark. אל תעתיקו קובצי JAR מותאמים אישית לספריות המערכת (ראו את האזהרה במאמר איך שולחים משימה). - לחלופין, אפשר לציין נתיב של Cloud Storage (
gs://your-bucket/your-jarfile.jar) או נתיב של מערכת קבצים מבוזרת של Hadoop (hdfs://path-to-jar.jar) לאחד מקובצי ה-JAR. (אם שולחים את המשימה באמצעות ה-API, צריך לציין את הנתיב הזה בשדהjarFileUris).
-
- מגדירים את סוג העבודה ל-Spark (Scala / Java) (
לוחצים על Submit כדי להתחיל את המשימה. אחרי שהמשימה מתחילה, היא מתווספת לרשימת המשימות.
לוחצים על מזהה המשימה כדי לפתוח את הדף Jobs, שבו אפשר לראות את פלט מנהל ההתקן של המשימה. מכיוון שהמשימה הזו מייצרת שורות פלט ארוכות שחורגות מרוחב חלון הדפדפן, אפשר לסמן את התיבה Line wrapping כדי להציג את כל טקסט הפלט, וכך לראות את התוצאה המחושבת של pi.
אפשר להציג את פלט מנהל ההתקן של המשימה משורת הפקודה באמצעות הפקודה gcloud dataproc jobs wait שמוצגת בהמשך (למידע נוסף, ראו הצגת פלט המשימה – פקודת GCLOUD).
מעתיקים ומדביקים את מזהה הפרויקט בתור הערך של הדגל --project, ואת מזהה המשימה (שמופיע ברשימת המשימות) בתור הארגומנט האחרון.
gcloud dataproc jobs wait job-id \ --project=project-id \ --region=region
הנה קטעי קוד מהפלט של מנהל ההתקן של משימת SparkPi לדוגמה:
... 2015-06-25 23:27:23,810 INFO [dag-scheduler-event-loop] scheduler.DAGScheduler (Logging.scala:logInfo(59)) - Stage 0 (reduce at SparkPi.scala:35) finished in 21.169 s 2015-06-25 23:27:23,810 INFO [task-result-getter-3] cluster.YarnScheduler (Logging.scala:logInfo(59)) - Removed TaskSet 0.0, whose tasks have all completed, from pool 2015-06-25 23:27:23,819 INFO [main] scheduler.DAGScheduler (Logging.scala:logInfo(59)) - Job 0 finished: reduce at SparkPi.scala:35, took 21.674931 s Pi is roughly 3.14189648 ... Job [c556b47a-4b46-4a94-9ba2-2dcee31167b2] finished successfully. driverOutputUri: gs://sample-staging-bucket/google-cloud-dataproc-metainfo/cfeaa033-749e-48b9-... ...
gcloud
כדי לשלוח משימה לאשכול של Managed Service for Apache Spark, מריצים את הפקודה gcloud dataproc jobs submit של ה-CLI של gcloud באופן מקומי בחלון הטרמינל או ב-Cloud Shell.
gcloud dataproc jobs submit job-command \ --cluster=cluster-name \ --region=region \ other dataproc-flags \ -- job-args
- מציגים את
hello-world.pyשנגישים באופן ציבורי ב-Cloud Storage. רשימת הקבצים:gcloud storage cat gs://dataproc-examples/pyspark/hello-world/hello-world.py
#!/usr/bin/python import pyspark sc = pyspark.SparkContext() rdd = sc.parallelize(['Hello,', 'world!']) words = sorted(rdd.collect()) print(words)
- שולחים את משימת PySpark ל-Managed Service for Apache Spark.
הפלט בטרמינל:gcloud dataproc jobs submit pyspark \ gs://dataproc-examples/pyspark/hello-world/hello-world.py \ --cluster=cluster-name \ --region=region
Waiting for job output... … ['Hello,', 'world!'] Job finished successfully.
- מריצים את הדוגמה של SparkPi שמותקנת מראש בצומת הראשי של האשכול ב-Managed Service for Apache Spark. (הנתיב
file:///usr/lib/spark/examples/jars/spark-examples.jarמיועד רק לדוגמאות שהותקנו מראש. לגבי יחסי תלות של JAR בהתאמה אישית, ראו את האזהרה בקטע איך שולחים משימה). הפלט בטרמינל:gcloud dataproc jobs submit spark \ --cluster=cluster-name \ --region=region \ --class=org.apache.spark.examples.SparkPi \ --jars=file:///usr/lib/spark/examples/jars/spark-examples.jar \ -- 1000
Job [54825071-ae28-4c5b-85a5-58fae6a597d6] submitted. Waiting for job output… … Pi is roughly 3.14177148 … Job finished successfully. …
REST
בקטע הזה מוסבר איך שולחים משימת Spark כדי לחשב את הערך המשוער של pi באמצעות ה-API jobs.submit של Managed Service for Apache Spark.
לפני שמשתמשים בנתוני הבקשה, צריך להחליף את הנתונים הבאים:
- project-id: מזהה הפרויקט ב- Google Cloud
- region: אזור האשכול
- clusterName: שם האשכול
ה-method של ה-HTTP וכתובת ה-URL:
POST https://dataproc.googleapis.com/v1/projects/project-id/regions/region/jobs:submit
תוכן בקשת JSON:
{
"job": {
"placement": {
"clusterName": "cluster-name"
},
"sparkJob": {
"args": [
"1000"
],
"mainClass": "org.apache.spark.examples.SparkPi",
"jarFileUris": [
"file:///usr/lib/spark/examples/jars/spark-examples.jar"
]
}
}
}
כדי לשלוח את הבקשה צריך להרחיב אחת מהאפשרויות הבאות:
אתם אמורים לקבל תגובת JSON שדומה לזו:
{
"reference": {
"projectId": "project-id",
"jobId": "job-id"
},
"placement": {
"clusterName": "cluster-name",
"clusterUuid": "cluster-Uuid"
},
"sparkJob": {
"mainClass": "org.apache.spark.examples.SparkPi",
"args": [
"1000"
],
"jarFileUris": [
"file:///usr/lib/spark/examples/jars/spark-examples.jar"
]
},
"status": {
"state": "PENDING",
"stateStartTime": "2020-10-07T20:16:21.759Z"
},
"jobUuid": "job-Uuid"
}
Java
- התקנה של ספריית הלקוח
- הגדרת Application Default Credentials
- מריצים את הקוד
Python
- התקנה של ספריית הלקוח
- הגדרת Application Default Credentials
- מריצים את הקוד
Go
- התקנה של ספריית הלקוח
- הגדרת Application Default Credentials
- מריצים את הקוד
Node.js
- התקנה של ספריית הלקוח
- הגדרת Application Default Credentials
- מריצים את הקוד
שליחת משימה ישירות באשכול
אם אתם רוצים להריץ משימה ישירות באשכול בלי להשתמש ב-Managed Service for Apache Spark, התחברו באמצעות SSH לצומת הראשי של האשכול והריצו את המשימה בצומת הראשי.
אחרי שיוצרים חיבור SSH למכונה הראשית של ה-VM, מריצים פקודות בחלון הטרמינל בצומת הראשי של האשכול כדי:
- פותחים מעטפת Spark.
- מריצים משימת Spark כדי לספור את מספר השורות בקובץ Python "hello-world" (בן שבע שורות) שנמצא בקובץ Cloud Storage שנגיש באופן ציבורי.
יוצאים מהמעטפת.
user@cluster-name-m:~$ spark-shell ... scala> sc.textFile("gs://dataproc-examples" + "/pyspark/hello-world/hello-world.py").count ... res0: Long = 7 scala> :quit
הרצת משימות Bash ב-Managed Service for Apache Spark
יכול להיות שתרצו להריץ סקריפט Bash כמשימה ב-Managed Service for Apache Spark, כי המנועים שבהם אתם משתמשים לא נתמכים כסוג העבודה ברמה העליונה ב-Managed Service for Apache Spark, או כי אתם צריכים לבצע הגדרה נוספת או חישוב של ארגומנטים לפני הפעלת משימה באמצעות hadoop או spark-submit מהסקריפט.
דוגמה ל-Pig
נניח שהעתקתם סקריפט Bash בשם hello.sh ל-Cloud Storage:
gcloud storage cp hello.sh gs://${BUCKET}/hello.shמכיוון שהפקודה pig fs משתמשת בנתיבי Hadoop, צריך להעתיק את הסקריפט מ-Cloud Storage ליעד שצוין בתור file:/// כדי לוודא שהוא נמצא במערכת הקבצים המקומית ולא ב-HDFS. הפקודות הבאות של sh מפנות למערכת הקבצים המקומית באופן אוטומטי, ולא צריך להוסיף להן את הקידומת file:///.
gcloud dataproc jobs submit pig --cluster=${CLUSTER} --region=${REGION} \
-e='fs -cp -f gs://${BUCKET}/hello.sh file:///tmp/hello.sh; sh chmod 750 /tmp/hello.sh; sh /tmp/hello.sh'לחלופין, מכיוון שהארגומנט --jars של שליחת משימות ב-Managed Service for Apache Spark מעביר קובץ לספרייה זמנית שנוצרה למשך חיי המשימה, אתם יכולים לציין את סקריפט המעטפת של Cloud Storage כארגומנט --jars:
gcloud dataproc jobs submit pig --cluster=${CLUSTER} --region=${REGION} \
--jars=gs://${BUCKET}/hello.sh \
-e='sh chmod 750 ${PWD}/hello.sh; sh ${PWD}/hello.sh'שימו לב שהארגומנט --jars יכול גם להפנות לסקריפט מקומי:
gcloud dataproc jobs submit pig --cluster=${CLUSTER} --region=${REGION} \
--jars=hello.sh \
-e='sh chmod 750 ${PWD}/hello.sh; sh ${PWD}/hello.sh'