שיטות מומלצות לשיפור הביצועים

במאמר הזה מוסבר איך לשפר את Cloud Storage FUSE באמצעות תכונות והגדרות מרכזיות של Cloud Storage FUSE, כדי להשיג תפוקה מקסימלית וביצועים אופטימליים, במיוחד עבור עומסי עבודה של בינה מלאכותית ולמידת מכונה (AI/ML) כמו אימון, הצגה וסימון נקודות ביקורת.

לתשומת ליבכם

לפני שמחילים את ההגדרות המומלצות בדף הזה, כדאי לקחת בחשבון את הדברים הבאים:

  • אפשר להחיל את ההגדרות המומלצות בדף הזה באמצעות השיטות הבאות:

  • מוודאים שאתם מריצים את הגרסה האחרונה של Cloud Storage FUSE. ההגדרות המומלצות רלוונטיות רק ל-Cloud Storage FUSE בגרסה 3.0 ואילך, ולמנהל התקן ה-CSI של Cloud Storage FUSE ל-Google Kubernetes Engine שפועל באשכולות GKE בגרסה 1.32.2-gke.1297001 ואילך.

  • במטמון של ההגדרות המומלצות נשמרים מטא-נתונים של Cloud Storage למשך זמן הפעלת המשימה, והם לא נבדקים אחרי הטעינה הראשונית של מערכת הקבצים. לכן, כדי להשיג ביצועים אופטימליים, מומלץ שמערכת הקבצים תהיה לקריאה בלבד או שהסמנטיקה של מערכת הקבצים תהיה כתיבה לקבצים חדשים, כלומר שהאפליקציות תמיד יכתבו לקבצים חדשים. עומסי העבודה הבאים של AI/ML הם מסוג write-to-new:

    • Checkpointing

    • הדרכה

    • השרת ממלא את הבקשה

    • שמירה במטמון של jax.jit()

  • התצורות המומלצות בדף הזה אומתו עבור מעבדים גרפיים ל-Cloud ומכונות גדולות מסוג Cloud TPU בהיקף גדול, שבהן יש כמות גדולה של זיכרון וממשק רשת עם רוחב פס גבוה. יכולים להיות הבדלים בין סוגי מכונות של מעבדים גרפיים ל-Cloud ו-Cloud TPU מבחינת מספר המשאבים הזמינים, כמו מעבד (CPU), זיכרון ואחסון מקומי, בתצורת צומת המארח שלהם. הדבר יכול להשפיע ישירות על הביצועים בהגדרות כמו:

    • A3 Ultra

    • A3 Mega – זיכרון של 1.8TiB, עם LSSD של 6TiB

    • Cloud TPU v5e – זיכרון בנפח 188GiB, ללא LSSD

    • Cloud TPU v5p – זיכרון של 448‎ GiB, ללא LSSD

    • Cloud TPU v6e‏ (Trillium) – זיכרון בנפח 1.5TiB, ללא LSSD

    • Cloud TPU 7x (Ironwood) – זיכרון בנפח 1.1TiB, ללא LSSD

תמיכה ב-Rapid Bucket

החל מגרסה 3.7.1, ‏ Cloud Storage FUSE תומך ב-Rapid Bucket עם נתיב קריאה אופטימלי.

נתיב הקריאה שעבר אופטימיזציה משפר משמעותית את הביצועים באמצעות שימוש באלגוריתם הקריאה מראש של ליבת Linux כברירת מחדל. כדי להשתמש בנתיב הקריאה האופטימלי הזה, צריך לבצע שינויים ספציפיים בהגדרות ברמת המחשב עבור הפרמטרים read_ahead_kb, max_background ו-congestion_threshold. בסביבות Google Kubernetes Engine ‏ (GKE) שבהן נעשה שימוש במנהל ההתקן של Cloud Storage FUSE CSI, ההגדרות האלה מנוהלות באופן מלא ומוחלות באופן אוטומטי. במכונות וירטואליות של Compute Engine ובסביבות אחרות שאינן GKE, כדי ש-Cloud Storage FUSE יחיל את השינויים האלה באופן אוטומטי, צריך לתת לו הרשאות sudo. אפשרות אחרת היא להגדיר את הפרמטרים האלה באופן ידני.

כשמשתמשים בנתיב הקריאה האופטימלי עבור Rapid Bucket, חשוב לזכור את ההתנהגויות והמגבלות הבאות:

  • תאימות למטמון קבצים ולקורא עם מאגר נתונים זמני: מכיוון שנתיב הקריאה האופטימלי מסתמך על אלגוריתם הקריאה מראש של ליבת המערכת, הוא לא תואם למטמון הקבצים ולקורא עם מאגר נתונים זמני של Cloud Storage FUSE. כברירת מחדל, התכונות האלה לא פעילות (no-op) ב-Rapid Bucket. אם עומס העבודה שלכם דורש את מטמון הקבצים או את קורא הנתונים הזמני, אתם צריכים להשבית באופן מפורש את קורא הליבה על ידי הגדרת enable-kernel-reader: false במהלך ההרכבה. כתוצאה מכך, Cloud Storage FUSE ישתמש בנתיב הקריאה הרגיל, שתואם לשמירה במטמון של קבצים ולקריאות עם מאגר זמני.
  • דרישות להרכבה: נתיב הקריאה החדש נתמך רק בהרכבות סטטיות. האפשרות הזו לא נתמכת כשמשתמשים בהרכבה דינמית.

שימוש בקטגוריות עם מרחב שמות היררכי

תמיד צריך להשתמש בקטגוריות עם מרחב שמות היררכי מופעל. מרחב שמות היררכי מארגן את הנתונים במבנה היררכי של מערכת קבצים, וכך הפעולות בתוך הדלי יעילות יותר. התוצאה היא זמני תגובה מהירים יותר ופחות קריאות לרשימה הכוללת לכל פעולה.

היתרונות של מרחב שמות היררכי כוללים:

  • קטגוריות עם מרחב שמות היררכי מספקות עד פי שמונה יותר שאילתות ראשוניות לשנייה (QPS) בהשוואה לקטגוריות שטוחות. מרחב שמות היררכי תומך ב-40,000 בקשות קריאה ראשוניות של אובייקטים בשנייה וב-8,000 בקשות כתיבה ראשוניות של אובייקטים, שזה הרבה יותר מהמגבלות של קטגוריות שטוחות ב-Cloud Storage FUSE, שמאפשרות רק 5,000 בקשות קריאה ראשוניות של אובייקטים בשנייה ו-1,000 בקשות כתיבה ראשוניות של אובייקטים.

  • מרחב שמות היררכי מספק שינוי שם אטומי של ספריות, שנדרש לנקודות ביקורת ב-Cloud Storage FUSE כדי להבטיח אטומיות. שימוש בקטגוריות עם מרחב שמות היררכי מועיל במיוחד כשמבצעים שמירת נקודות ביקורת בהיקף נרחב, כי מסגרות ML משתמשות בפקודה מהירה ואטומיקית של שינוי שם של ספרייה כדי להשלים את נקודות הביקורת, והפקודה הזו נתמכת רק בקטגוריות עם מרחב שמות היררכי. אם אתם בוחרים לא להשתמש בקטגוריה עם מרחב שמות היררכי מופעל, כדאי לעיין במאמר בנושא הגדלת מגבלת השינוי של שם הקטגוריה עבור קטגוריות ללא מרחב שמות היררכי.

במאמר יצירת קטגוריות עם מרחב שמות היררכי מופעל מוסבר איך ליצור קטגוריה עם מרחב שמות היררכי מופעל. איך לטעון קטגוריות עם מרחב שמות היררכי מרחב שמות היררכי נתמך בגרסאות Google Kubernetes Engine‏ ‎1.31.1-gke.2008000 ואילך.

ביצוע טעינה ספציפית לספרייה

אם רוצים לגשת לספרייה ספציפית בתוך קטגוריה, אפשר לטעון רק את הספרייה הספציפית באמצעות אפשרות הטעינה only-dir במקום לטעון את כל הקטגוריה. ביצוע פעולת mount ספציפית לספרייה מאיץ את הקריאות לרשימה ומצמצם את המספר הכולל של הקריאות לרשימה ולסטטוס, כי הוא מגביל את מספר הספריות שצריך לעבור כדי לפתור שם קובץ. הסיבה לכך היא שקריאות ל-LookUpInode ובקשות גישה לקטגוריה או לספרייה יוצרות באופן אוטומטי קריאות לרשימה ולסטטוס לכל קובץ או ספרייה בנתיב.

כדי לטעון ספרייה ספציפית, משתמשים באחת מהשיטות הבאות:

Google Kubernetes Engine

כדי להשתמש בנפחי אחסון מתמיד, צריך להשתמש בהגדרת הטעינה הבאה עם מנהל ההתקן של ה-CSI של Cloud Storage FUSE ל-Google Kubernetes Engine:

mountOptions:
    - only-dir:DIRECTORY_NAME

לנפחים זמניים, מוסיפים את הגדרות ההרכבה ל-volumeAttributes.mountOptions, כשהדגלים מופרדים באמצעות פסיקים:

mountOptions: "OTHER_OPTIONS,only-dir:DIRECTORY_NAME"

מחליפים את DIRECTORY_NAME בשם של הספרייה שרוצים לטעון.

Compute Engine

מריצים את הפקודה gcsfuse --only-dir כדי לטעון ספרייה ספציפית במכונה וירטואלית של Compute Engine:

gcsfuse --only-dir DIRECTORY_NAME BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה שרוצים לטעון את הספרייה לתוכה.

  • DIRECTORY_NAME הוא שם הספרייה שרוצים לטעון.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

מידע נוסף על טעינת ספריות זמין במאמר טעינת ספרייה בתוך קטגוריה.

הגדלת ערכי מטמון המטא-נתונים

כדי לשפר את הביצועים של קריאות חוזרות, אפשר להגדיר את Cloud Storage FUSE כך שישמור במטמון כמות גדולה של מטא-נתונים ויעקוף את תפוגת המטא-נתונים. כך נמנעות בקשות חוזרות למטא-נתונים אל Cloud Storage, והביצועים משתפרים באופן משמעותי.

הגדלת ערכי מטמון המטא-נתונים מועילה לעומסי עבודה עם קריאות חוזרות, כדי להימנע מקריאות חוזרות ל-Cloud Storage, ולנפחים לקריאה בלבד שבהם אפשר להגדיר TTL אינסופי.

לפני שמגדילים את ערכי מטמון המטא-נתונים, כדאי לשים לב לנקודות הבאות:

  • אורך חיים (TTL) אינסופי צריך להיות מוגדר רק לנפחים שהם לקריאה בלבד או לכתיבה רק לנפחים חדשים.

  • צריך להגדיל את המטמון של המטא-נתונים רק בצמתים עם הגדרות זיכרון גדולות, כי הוא שומר במטמון את כל המטא-נתונים של נקודת הגישה שצוינה בכל צומת, ומבטל את הצורך בגישה נוספת ל-Cloud Storage.

  • ההגדרות בקטע הזה שומרות במטמון את כל המטא-נתונים שהייתה אליהם גישה עם TTL אינסופי, מה שיכול להשפיע על עקביות הנתונים כששינויים מתבצעים באותה קטגוריה של Cloud Storage על ידי לקוח אחר, למשל, החלפה של קובץ או מחיקה של קובץ.

  • כדי לוודא שצריכת הזיכרון לא מושפעת, צריך לוודא שכמות הזיכרון שנצרכת על ידי מטמון המטא-נתונים מקובלת עליכם. הכמות הזו יכולה להגיע לכמה גיגה-בייט ותלויה במספר הקבצים בדליים המחוברים ובמספר נקודות החיבור שנמצאות בשימוש. לדוגמה, המטא-נתונים של כל קובץ תופסים בערך ‎1.5 KiB של זיכרון, ולכן המטא-נתונים של מיליון קבצים תופסים בערך ‎1.5 GiB של זיכרון. מידע נוסף זמין במאמר סקירה כללית על שמירה במטמון.

כדי להגדיר את Cloud Storage FUSE כך שישמור במטמון כמות גדולה של מטא-נתונים ויעקוף את תפוגת המטא-נתונים, פועלים לפי ההוראות הבאות:

gcsfuse אפשרויות

gcsfuse --metadata-cache-ttl-secs=-1 \
      --stat-cache-max-size-mb=-1 \
      BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

קובץ תצורה

metadata-cache:
stat-cache-max-size-mb: -1
ttl-secs: -1

Google Kubernetes Engine

  mountOptions:
      - metadata-cache:ttl-secs:-1
      - metadata-cache:stat-cache-max-size-mb:-1

Compute Engine

gcsfuse --metadata-cache-ttl-secs=-1 \
      --stat-cache-max-size-mb=-1 \
      BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

אכלוס מראש של מטמון המטא-נתונים

לפני שמריצים עומס עבודה, מומלץ לאכלס מראש את מטמון המטא-נתונים. כך משפרים באופן משמעותי את הביצועים ומצמצמים באופן ניכר את מספר הקריאות למטא-נתונים ב-Cloud Storage, במיוחד אם משתמשים בשדה implicit-dirs או באפשרות --implicit-dirs. מנהל התקן ה-CSI של Cloud Storage FUSE ל-GKE מספק API שמטפל באכלוס מראש של מטמון המטא-נתונים. אפשר לעיין במאמר שימוש באחזור מראש של מטא-נתונים כדי לאכלס מראש את מטמון המטא-נתונים.

כדי לאכלס מראש את מטמון המטא-נתונים, משתמשים באחת מהשיטות הבאות:

Google Kubernetes Engine

מגדירים את הדגל של מאפיין עוצמת הקול של CSI‏ gcsfuseMetadataPrefetchOnMount לערך true:

בגרסאות Google Kubernetes Engine‏ 1.32.1-gke.1357001 ואילך, אפשר להפעיל אחזור מראש של מטא-נתונים עבור נפח נתון באמצעות אפשרות ההגדרה gcsfuseMetadataPrefetchOnMount בשדה volumeAttributes בהגדרה של PersistentVolume. אין צורך ב-method‏ initContainer כשמשתמשים באפשרות ההגדרה gcsfuseMetadataPrefetchOnMount.

  apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: training-bucket-pv
  spec:
    ...
    csi:
      volumeHandle: BUCKET_NAME
      volumeAttributes:
        ...
        gcsfuseMetadataPrefetchOnMount: "true"
  

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

יכול להיות שיהיו הבדלים במשאבים של קובץ ה-Init container בהתאם לתוכן של ה-bucket ולפריסה ההיררכית, לכן מומלץ להגדיר משאבי sidecar מותאמים אישית לאחזור מראש של מטא-נתונים כדי להגדיל את המגבלות.

Linux

מריצים באופן ידני את הפקודה ls -R בנקודת הטעינה של Cloud Storage FUSE כדי להציג ברשימה באופן רקורסיבי את כל הקבצים ולאכלס מראש את מטמון המטא-נתונים:

ls -R MOUNT_POINT > /dev/null

מחליפים את מה שכתוב בשדות הבאים:

MOUNT_POINT: הנתיב לנקודת הטעינה של Cloud Storage FUSE.

Compute Engine

מריצים באופן ידני את הפקודה ls -R בנקודת הטעינה של Cloud Storage FUSE כדי להציג ברשימה באופן רקורסיבי את כל הקבצים ולאכלס מראש את מטמון המטא-נתונים:

ls -R MOUNT_POINT > /dev/null

מחליפים את מה שכתוב בשדות הבאים:

MOUNT_POINT: הנתיב לנקודת הטעינה של Cloud Storage FUSE.

הפעלת שמירת קבצים במטמון והורדות מקבילות

שמירת קבצים במטמון מאפשרת לכם לאחסן נתונים של קבצים שאתם ניגשים אליהם לעיתים קרובות באופן מקומי במחשב, וכך לקצר את זמן הקריאה החוזרת ולהוזיל את העלויות של Cloud Storage. כשמפעילים שמירת קבצים במטמון, גם הורדות מקבילות מופעלות באופן אוטומטי. הורדות מקבילות משתמשות בכמה תהליכי עבודה כדי להוריד קובץ במקביל, באמצעות ספריית מטמון הקבצים כמאגר אחזור מראש, וכתוצאה מכך זמן הטעינה של המודל מהיר פי תשעה.

במאמר הפעלה והגדרה של התנהגות שמירה במטמון של קבצים מוסבר איך להפעיל ולהגדיר שמירה במטמון של קבצים והורדות מקבילות. כדי להשתמש בהגדרות לדוגמה, ראו הגדרות לדוגמה להפעלת שמירת קבצים במטמון והורדות מקבילות.

שיקולים לגבי שימוש במטמון קבצים והורדות מקבילות במעבדים גרפיים ל-Cloud וב-Cloud TPU

אפשר לארח את מטמון הקבצים ב-Local SSD, ב-RAM, ב-Persistent Disk או ב-Google Cloud Hyperdisk, בהתאם להנחיות הבאות. בכל המקרים, הנתונים או קובץ גדול בודד צריכים להיכנס לקיבולת הזמינה של ספריית מטמון הקבצים, שמוגדרת באמצעות השדה max-size-mb או האפשרות --file-cache-max-size-mb.

שיקולים לגבי מעבדים גרפיים ל-Cloud

אחסוני SSD מקומיים מתאימים במיוחד לנתוני אימון ולהורדות של נקודות ביקורת. מעבדים גרפיים ל-Cloud סוגי מכונות כוללים קיבולת SSD שאפשר להשתמש בה, כמו סוגי מכונות A4 שכוללים 12TiB של SSD.

  • דיסק RAM מספק את הביצועים הכי טובים לטעינת משקלי המודל, כי הגודל שלהם קטן בהשוואה לכמות ה-RAM שלא בשימוש במערכת.

  • אפשר להשתמש ב-Persistent Disk או ב-Google Cloud Hyperdisk כמטמון.

שיקולים לגבי Cloud TPU

‫Cloud TPU לא תומך בכונני SSD מקומיים. אם משתמשים בשמירת קבצים במטמון ב-Cloud TPU בלי לבצע שינויים, המיקום שמוגדר כברירת מחדל הוא נפח האתחול, וזה לא מומלץ וגורם לביצועים ירודים.

במקום נפח האתחול, מומלץ להשתמש בדיסק RAM, שהוא עדיף בגלל הביצועים שלו ואין עלות מצטברת. עם זאת, הגודל של דיסק RAM מוגבל בדרך כלל, והוא הכי שימושי להצגת משקלים של מודלים או להורדות של נקודות ביקורת, בהתאם לגודל של נקודת הביקורת ולזיכרון ה-RAM הזמין. בנוסף, מומלץ להשתמש ב-Persistent Disk וב-Google Cloud Hyperdisk למטרות שמירת נתונים במטמון.

דוגמה להגדרה של הפעלת שמירת קבצים במטמון והורדות מקבילות

כברירת מחדל, מטמון הקבצים משתמש ב-SSD מקומי אם מצב ephemeral-storage-local-ssd מופעל בצומת Google Kubernetes Engine. אם אין SSD מקומי זמין, למשל במכונות Cloud TPU, מטמון הקבצים משתמש בדיסק האתחול של הצומת של Google Kubernetes Engine, וזה לא מומלץ. במקרה כזה, אפשר להשתמש בדיסק RAM כספריית המטמון, אבל צריך לקחת בחשבון את כמות ה-RAM שזמינה לשמירת קבצים במטמון לעומת מה שנדרש ל-Pod.

gcsfuse אפשרויות

gcsfuse --file-cache-max-size-mb=-1 \
      --file-cache-cache-file-for-range-read=true \
      --file-cache-enable-parallel-downloads=true \
      BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

file-cache:
  max-size-mb: -1
  cache-file-for-range-read: true
  enable-parallel-downloads: true

מעבדים גרפיים ל-Cloud

mountOptions:
    - file-cache:max-size-mb:-1
    - file-cache:cache-file-for-range-read:true
    - file-cache:enable-parallel-downloads:true

# RAM disk file cache if LSSD not available. Uncomment to use
# volumes:
#   - name: gke-gcsfuse-cache
#     emptyDir:
#       medium: Memory

Cloud TPU

mountOptions:
    - file-cache:max-size-mb:-1
    - file-cache:cache-file-for-range-read:true
    - file-cache:enable-parallel-downloads:true

volumes:
    - name: gke-gcsfuse-cache
      emptyDir:
        medium: Memory

Compute Engine

gcsfuse --file-cache-max-size-mb=-1 \
      --file-cache-cache-file-for-range-read=true \
      --file-cache-enable-parallel-downloads=true \
      BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

השבתת רשומות מטמון של נתונים שליליים

כברירת מחדל, Cloud Storage FUSE שומר במטמון רשומות stat שליליות, כלומר רשומות של קבצים שלא קיימים, עם TTL של חמש שניות. בסביבות עבודה שבהן קבצים נוצרים או נמחקים לעיתים קרובות, כמו בנקודות ביקורת מבוזרות, הערכים ששמורים במטמון עלולים להתיישן במהירות, מה שמוביל לבעיות בביצועים. כדי למנוע את הבעיה הזו, מומלץ להשבית את מטמון הנתונים הסטטיים השליליים עבור עומסי עבודה של אימון, הצגה ונקודות ביקורת באמצעות השדה negative-ttl-secs או האפשרות --metadata-cache-negative-ttl-secs.

כדי להשבית את מטמון הנתונים השליליים:

אפשרות gcsfuse

gcsfuse --metadata-cache-negative-ttl-secs=0 \
  BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

metadata-cache:
 negative-ttl-secs: 0

Google Kubernetes Engine

mountOptions:
    - metadata-cache:negative-ttl-secs:0

Compute Engine

gcsfuse --metadata-cache-negative-ttl-secs=0 \
  BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

הפעלת כתיבה לסטרימינג

העלאה של נתונים באמצעות כתיבה בזמן אמת (Streaming writes) מעלה את הנתונים ישירות ל-Cloud Storage בזמן הכתיבה, וכך מצמצמת את זמן האחזור ואת השימוש בשטח הדיסק. האפשרות הזו שימושית במיוחד לכתיבה רציפה של נתונים בכמויות גדולות, כמו נקודות ביקורת. הזרמת כתיבה מופעלת כברירת מחדל ב-Cloud Storage FUSE מגרסה 3.0 ואילך.

אם כתיבה של נתונים בזמן אמת לא מופעלת כברירת מחדל, פועלים לפי ההוראות הבאות כדי להפעיל אותה. כדי להפעיל כתיבה בהזרמה, צריך להשתמש ב-Cloud Storage FUSE גרסה 3.0, שזמינה ב-Google Kubernetes Engine גרסה 1.32.1-gke.1729000 ואילך.

אפשרות gcsfuse

gcsfuse --enable-streaming-writes=true \
  BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

write:
 enable-streaming-writes: true

Google Kubernetes Engine

mountOptions:
    - write:enable-streaming-writes:true

Compute Engine

gcsfuse --enable-streaming-writes=true \
  BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

הפעלת קריאות עם מאגר

קריאות עם מאגר זמני יכולות לשפר את ביצועי הקריאה הסדרתית של קבצים גדולים פי שניים עד חמישה, על ידי אחזור מראש של חלקים מאובייקט Cloud Storage באופן אסינכרוני למאגר זמני בזיכרון. כך אפשר להציג קריאות עוקבות מהמאגר במקום לדרוש קריאות לרשת.

לפני שמפעילים קריאות עם מאגר זמני, כדאי לשים לב לנקודות הבאות:

  • קריאות עם מאגר זמני לא תואמות לשמירת קבצים במטמון. אם גם קריאות עם מאגר וגם שמירת קבצים במטמון מופעלות, שמירת קבצים במטמון מקבלת עדיפות וקריאות עם מאגר מתעלמות.

  • קריאות עם מאגר זמני יכולות לתפוס הרבה זיכרון ומשאבי מחשוב.

כדי להפעיל קריאות עם מאגר זמני, פועלים לפי ההוראות הבאות:

אפשרויות CLI

gcsfuse --enable-buffered-read=true \
  BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

read:
 enable-buffered-read: true

הגדלת גודל הקריאה מראש של ליבת המערכת

במקרה של עומסי עבודה שכוללים בעיקר קריאות רציפות של קבצים גדולים, כמו שחזור של נקודות ביקורת (checkpoint) והצגה של קבצים, הגדלת הגודל של הקריאה מראש יכולה לשפר משמעותית את הביצועים. אפשר לעשות זאת באמצעות read_ahead_kb פרמטר ליבת Linux במחשב המקומי. מומלץ להגדיל את הפרמטר read_ahead_kb של ליבת המערכת ל-1MB במקום להשתמש בכמות ברירת המחדל של 128KB שמוגדרת ברוב הפצות לינוקס. במכונות של Compute Engine, נדרשות ההרשאות sudo או root כדי להגדיל את פרמטר הליבה.

כדי להגדיל את פרמטר הליבה read_ahead_kb ל-1MB עבור ספרייה ספציפית של Cloud Storage FUSE, פועלים לפי ההוראות הבאות. צריך לטעון את הקטגוריה ל-Cloud Storage FUSE לפני שמריצים את הפקודה, אחרת פרמטר הליבה לא יגדל.

בקטגוריות אזוריות, Cloud Storage FUSE מנהל באופן אוטומטי את פרמטר הליבה read_ahead_kbב-Google Kubernetes Engine מגרסה 1.35.0-gke.3047001 ואילך, ובסביבות Compute Engine באמצעות Cloud Storage FUSE מגרסה 3.7.0 ואילך. הפעולה הזו מתבצעת באופן אוטומטי, ולכן האפשרות read_ahead_kb mount לא רלוונטית יותר. כל ערך שתספקו יתעלמו ממנו. הערה: בסביבות של Compute Engine, כדי שמערכת Cloud Storage FUSE תנהל את הפרמטר הזה באופן אוטומטי, צריך לתת לה הרשאות root או הרשאות sudo ללא סיסמה.

Google Kubernetes Engine

mountOptions:
    - read_ahead_kb=1024

Compute Engine

export MOUNT_POINT=/path/to/mount/point
echo 1024 | sudo tee /sys/class/bdi/0:$(stat -c "%d" $MOUNT_POINT)/read_ahead_kb

מחליפים את מה שכתוב בשדות הבאים:

  • /path/to/mount/point: הנתיב במערכת הקבצים המקומית שבה הקטגוריה של Cloud Storage מותקנת.

השבתת Security Token Service כדי למנוע בדיקות מיותרות

למנהל ההתקן של ה-CSI של Cloud Storage FUSE ל-Google Kubernetes Engine יש בדיקות גישה כדי להבטיח את האפשרות לשחזר קבוצות Pod. זאת בגלל טעויות בהגדרות של משתמשים בנוגע לקישורי זהויות של עומסי עבודה בין הקטגוריה לחשבון השירות של GKE, שיכולות להגיע למכסות ברירת המחדל של Security Token Service API בקנה מידה גדול. אפשר להשבית את האפשרות הזו על ידי הגדרת מאפיין עוצמת הקול skipCSIBucketAccessCheck של מנהל ההתקן CSI של Persistent Volume. כדי למנוע כשלים בהרכבה של ה-Pod, מומלץ לוודא שלחשבון השירות של GKE יש את הגישה הנכונה לקטגוריית Cloud Storage של היעד.

בנוסף, אם אשכול Google Kubernetes Engine כולל יותר מ-6,000 צמתים, צריך להגדיל את מכסת Security Token Service מעבר לערך ברירת המחדל של 6000. אחרת, יכול להיות שיוצגו שגיאות 429 בהטמעות בקנה מידה גדול. צריך להגדיל את המכסה של Security Token Service דרך הדף 'מכסות ומגבלות'. מומלץ להגדיר את המכסה כך שתהיה שווה למספר הנפחים. לדוגמה, אם יש 10,000 נפחים באשכול, צריך להגדיל את המכסה ל-10000.

כדי להגדיר את מאפיין עוצמת הקול skipCSIBucketAccessCheck, אפשר להיעזר בהגדרות לדוגמה הבאות:

  volumeAttributes:
      - skipCSIBucketAccessCheck: "true"
   

אופטימיזציה של הביצועים לנקודות ביקורת של OCDBT Orbax

כדי לשפר את הביצועים של השחזור וההצגה של נקודות ביקורת (checkpoint) בפורמט OCDBT של Orbax בעומסי עבודה, אפשר להיעזר בהנחיות הבאות:

  • הגדרת דפים שקופים גדולים לערך always: הגדרת דפים שקופים גדולים לערך always משפרת את הביצועים על ידי הפחתת פיצול הזיכרון וקריאות המערכת. ההגדרה הזו יעילה במיוחד כשמוקצים נתחים גדולים של זיכרון, וזה קורה בדרך כלל בעומסי העבודה האלה. ההגדרה הזו מוגדרת כברירת מחדל במכונות Cloud TPU, וצריך להגדיר אותה רק בסוגים אחרים של מכונות. כדי להפעיל דפים שקופים גדולים במחשב המקומי, מריצים את הפקודה הבאה עם הרשאות root.

    echo always | tee /sys/kernel/mm/transparent_hugepage/enabled
    

    בסביבת GKE, אפשר ליצור Pod עם הרשאות כדי לעשות את אותו הדבר.

  • הגדלת גודל הקריאה מראש של הליבה: הגדלת גודל הקריאה מראש של הליבה ל-1,024KB משפרת את ביצועי הקריאה הסדרתית. מידע נוסף זמין במאמר בנושא הגדלת הגודל של קריאה מראש של ליבת המערכת.

  • הגדרה של ocdbt_target_data_file_size ל-200 MiB: מגדירים את ocdbt_target_data_file_size ל-200 MiB, שהוא הערך האופטימלי לביצועי קריאה עם Cloud Storage FUSE.

  • שימוש במטמון DNS: מטמון DNS מקטין את זמן האחזור על ידי שמירת חיפושי DNS במטמון באופן מקומי. ב-GKE, אפשר להפעיל את NodeLocal DNSCache כדי לשמור במטמון את בדיקות ה-DNS. אפשר גם להשתמש ב-Cloud Storage FUSE גרסה 3.5 ואילך ב-Compute Engine, או ב-GKE גרסה 1.34.1-gke.3899000 ואילך בסביבת GKE.

שיקולים נוספים לגבי ביצועים

בנוסף לאופטימיזציות העיקריות שצוינו, יש עוד כמה גורמים שיכולים להשפיע באופן משמעותי על הביצועים הכוללים של Cloud Storage FUSE. בקטעים הבאים מתוארים שיקולים נוספים לגבי ביצועים שכדאי לקחת בחשבון כשמשתמשים ב-Cloud Storage FUSE.

הגדלת מגבלת השינוי של שמות של דליים שאינם דליים עם מרחבי שמות היררכיים

תמיד צריך לבצע את העברת עומסי העבודה לנקודות ביקורת באמצעות קטגוריה שמופעל בה מרחב שמות היררכי, כי היא מאפשרת שינוי שם אטומי ומהיר יותר ו-QPS גבוה יותר לקריאות ולכתיבות. עם זאת, אם אתם מוכנים לקחת את הסיכון ששינוי השם של הספריות לא יהיה אטומי וייקח יותר זמן, אתם יכולים להשתמש בשדה rename-dir-limit או באפשרות --rename-dir-limit אם אתם מבצעים יצירת נקודות ביקורת באמצעות קטגוריות ללא מרחב שמות היררכי, כדי להגדיר מגבלה על מספר הקבצים או הפעולות שקשורות לפעולת שינוי השם של הספריות בכל זמן נתון.

מומלץ להגדיר את ההגדרה הזו לערך גבוה כדי למנוע כשלים בנקודות ביקורת. מכיוון ש-Cloud Storage FUSE משתמש במרחב שמות שטוח והאובייקטים הם בלתי ניתנים לשינוי, פעולה של שינוי שם של ספרייה כוללת שינוי שם ומחיקה של כל הקבצים בתוך הספרייה. אפשר לקבוע את מספר הקבצים שיושפעו מפעולת שינוי השם באמצעות האפשרות rename-dir-limit gcsfuse.

כדי להגדיר את אפשרות ההגדרה rename-dir-limit:

אפשרות gcsfuse

gcsfuse --rename-dir-limit=200000 \
  BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

file-system:
 rename-dir-limit: 200000

Google Kubernetes Engine

mountOptions:
    - rename-dir-limit=200000

Compute Engine

gcsfuse --rename-dir-limit=200000 \
  BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

שמירה במטמון של רשימת ליבות

מטמון הרשימות הוא מטמון של רשימות קבצים וספריות, או של תגובות ls, שמשפר את המהירות של פעולות ברשימות. בניגוד למטמון של נתוני stat שמנוהל על ידי Cloud Storage FUSE, המטמון של רשימת הקבצים נשמר במטמון הדפים של ליבת מערכת ההפעלה, והליבה שולטת בו בהתאם לזמינות הזיכרון.

הפעלת שמירת מטמון של רשימת ליבות מועילה במיוחד בתרחישי השימוש הבאים:

  • עומסי עבודה עם רישומים חוזרים בספרייה: התצורה הזו שימושית במיוחד לעומסי עבודה שמבצעים רישומים מלאים בספרייה בתדירות גבוהה, כמו הפעלות של אימון AI/ML. השיפור הזה יכול להועיל לעומסי עבודה של הצגת מודלים ושל אימון מודלים.

  • טעינות לקריאה בלבד: מומלץ להשתמש במטמון של רשימות עם טעינות לקריאה בלבד כדי למנוע בעיות עקביות.

צריך להפעיל את האפשרות 'שמירת רשימת ליבות במטמון' בזהירות, ולהשתמש בה רק אם מערכת הקבצים היא לקריאה בלבד, ולא צפויים שינויים בתוכן של ספרייה במהלך ההפעלה של עבודה. הסיבה לכך היא שאם משתמשים בדגל הזה, האפליקציה המקומית אף פעם לא רואה עדכונים, במיוחד אם הערך של TTL מוגדר ל--1.

לדוגמה, Client 1 מפרט את directoryA, ולכן directoryA הוא תושב במטמון של רשימת הליבה. לקוח 2 יוצר את fileB ב-directoryA בקטגוריה של Cloud Storage. לקוח 1 בודק באופן רציף אם יש fileB ב-directoryA. המשמעות היא שהוא בודק את הרשומה במטמון של רשימת הליבה, והוא אף פעם לא עובר ברשת. לקוח 1 לא רואה שיש קובץ חדש בספרייה כי רשימת הקבצים מוגשת באופן רציף ממטמון הרשימה של ליבת המערכת המקומית. ‫Client 1 מגיע למצב timeout והתוכנית נכשלת.

כדי להפעיל שמירת רשימות במטמון:

אפשרות gcsfuse

gcsfuse --kernel-list-cache-ttl-secs=-1 \
  BUCKET_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

קובץ תצורה

file-system:
 kernel-list-cache-ttl-secs: -1

Google Kubernetes Engine

mountOptions:
    - file-system:kernel-list-cache-ttl-secs:-1

Compute Engine

gcsfuse --kernel-list-cache-ttl-secs=-1 \
  BUCKET_NAME MOUNT_POINT

מחליפים את מה שכתוב בשדות הבאים:

  • BUCKET_NAME הוא שם הקטגוריה.

  • MOUNT_POINT היא הספרייה המקומית שאליה תטענו את הקטגוריה. לדוגמה, /path/to/mount/point.

כשמשתמשים באפשרות ההרכבה file-system:kernel-list-cache-ttl-secs, הערכים מייצגים את הדברים הבאים:

  • ערך חיובי מייצג את ה-TTL בשניות לשמירת התגובה של רשימת הספריות במטמון הדפים של ליבת המערכת.

  • אם הערך הוא -1, המערכת מדלגת על תפוגת התוקף של הרשומה ומחזירה את תגובת הרשימה מהמטמון כשהיא זמינה.

שימוש במטמון של קומפילציה מתמשכת (JIT) של JAX עם Cloud Storage FUSE

‫JAX תומך במטמון Just-In-Time‏ (JIT), מטמון אופציונלי של קומפילציה מתמשכת שמאחסן ארטיפקטים של פונקציות שעברו קומפילציה. כשמשתמשים במטמון הזה, אפשר להאיץ באופן משמעותי את ההרצות הבאות של הסקריפט, כי לא צריך לבצע שלבי קומפילציה מיותרים.

כדי להפעיל שמירת מטמון בזמן אמת, אתם צריכים לעמוד בדרישות הבאות:

  • שימוש בגרסה האחרונה של JAX: כדי להשתמש בתכונות ובאופטימיזציות האחרונות של מטמון, צריך להשתמש בגרסה 0.5.1 ואילך של JAX.

  • מקסום קיבולת המטמון: כדי למנוע ירידה בביצועים בגלל פינוי מטמון, כדאי להגדיר גודל מטמון ללא הגבלה, במיוחד אם רוצים לבטל את הגדרות ברירת המחדל. כדי לעשות את זה, צריך להגדיר את משתנה הסביבה:

    export JAX_COMPILATION_CACHE_MAX_SIZE=-1
    
  • מוודאים את קובץ ה-YAML של ה-pod של מחסום הבדיקה: משתמשים בהגדרת מחסום הבדיקה עבור נקודת ה-mount של מטמון ה-JIT של JAX.

הגדרה של ניהול זרימת נתונים (RFS) לקבלת נתונים ב-A4X

במכונות Compute Engine, התכונות Receive Packet Steering (RPS) ו-Receive Flow Steering (RFS) פועלות יחד כדי לשפר את ביצועי הרשת. הן עושות זאת על ידי חלוקה חכמה של עיבוד חבילות המידע ברשת בין כמה מעבדים. מומלץ להשתמש בהגדרות האלה לתעבורת נתונים ברשת בקצב גבוה בסוגי מכונות כמו A4X.

  • התכונה RPS מחלקת חבילות נתונים נכנסות ברשת בין מעבדים שונים לצורך עיבוד. כך אפשר לאזן את העומס ולמנוע ממעבד יחיד להפוך לצוואר בקבוק, וזה שימושי במיוחד לתנועת נתונים ברשת בקצב גבוה ויכול לתרום להפחתת זמן האחזור.

  • ה-RFS מבוסס על ה-RPS, ומשפר את יעילות המטמון של המעבד כדי להפחית עוד יותר את זמן האחזור ברשת. היא מכוונת חבילות ליבת ה-CPU הספציפית שבה האפליקציה שתשתמש בחבילות פועלת, וכך מגדילה את שיעור הפגיעה במטמון הנתונים של ה-CPU ומובילה לזמן אחזור נמוך יותר ברשת.

יתרונות בביצועים

השימוש ב-RFS משפר משמעותית את הביצועים במגוון עומסי עבודה, ומגדיל את קצב העברת הנתונים בעד 40%.

לתשומת ליבכם

ההגדרות האלה יעילות בעומס, אבל יכול להיות שהן לא יועילו בכל התרחישים:

  • עומסי עבודה עם שרשור יחיד או זרימה יחידה: עומס עבודה עם זרימה יחידה מתרחש כשכל התנועה ברשת משתמשת בחיבור רשת יחיד (לדוגמה, העברה של קובץ גדול יחיד דרך חיבור TCP אחד). האפליקציות האלה לרוב לא נהנות מיתרון משמעותי, ואפילו עשויות לחוות ירידה קלה בנפח התעבורה (למשל, 7.7% בבדיקות ספציפיות של nginx). אפליקציות עם זרימה יחידה הן בדרך כלל נדירות בהקשרים של ביצועים גבוהים.

  • העברה תכופה של שרשורים: אם שרשורים של אפליקציות עוברים לעיתים קרובות בין מעבדי CPU,‏ RFS מעדכן כל הזמן את המיפויים של מעבדי ה-CPU(לדוגמה, אפליקציות שמשתמשות במאגרי שרשורים גדולים של עובדים דינמיים, שבהם בקשות מועברות לעיתים קרובות בין ליבות שונות), מה שעלול להוביל לתנועה מוגזמת בין מעבדי ה-CPU ולסידור מחדש של מנות.

סקריפט הגדרות

מריצים את הסקריפט הבא במערכת ההפעלה של האורח במופע Compute Engine. הסקריפט דורש הרשאות sudo או root כדי לשנות את הפרמטרים של ליבת המערכת.

הסקריפט מפעיל RPS, ממפה תורים ברשת למעבדים זמינים בשיטת Round-Robin ומגדיר את הגודל של טבלת הזרימה לכל תור ל-65536.

#!/bin/bash
set -e

# Note: This script uses 'apt' and is intended for Debian-based systems.
# If 'iproute2' is not found, you may need to run 'sudo apt update' first.
sudo apt install -y iproute2

# This script enables and configures RPS (Receive Packet Steering) and RFS
# (Receive Flow Steering) for the primary network interface.
# It creates a 1:1 mapping of CPUs to receive queues and sets a specific
# flow count for each queue.

# --- Configuration ---
# The desired number of flow entries per receive queue.
RPS_FLOW_CNT_PER_QUEUE=65536

# --- Script Body ---

# 1. Auto-detect the primary network interface.
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n 1)

if [ -z "$INTERFACE" ]; then
  echo "Error: Could not determine the primary network interface."
  exit 1
fi
echo "Primary network interface detected: $INTERFACE"

echo "Starting RPS/RFS configuration for interface: $INTERFACE"

# 2. Determine the number of receive queues for the interface.
NUM_QUEUES=$(ls -d /sys/class/net/$INTERFACE/queues/rx-* 2>/dev/null | wc -l)
if [ "$NUM_QUEUES" -eq 0 ]; then
  echo "Error: No receive queues found for interface $INTERFACE."
  echo "Please check if the network driver supports multi-queue."
  exit 1
fi
echo "Found $NUM_QUEUES receive queues for interface $INTERFACE."

# 3. Determine the number of CPUs.
NUM_CPUS=$(nproc)
if [ -z "$NUM_CPUS" ] || [ "$NUM_CPUS" -eq 0 ]; then
  echo "Error: Could not determine the number of CPUs."
  exit 1
fi
echo "Found $NUM_CPUS CPUs."

# 4. Calculate and set the total socket flow entries.
# This is the total number of entries in the global socket flow table.
RPS_SOCK_FLOW_ENTRIES=$((NUM_QUEUES * RPS_FLOW_CNT_PER_QUEUE))
echo "Setting the total RPS socket flow entries to $RPS_SOCK_FLOW_ENTRIES..."
if ! echo "$RPS_SOCK_FLOW_ENTRIES" | sudo tee /proc/sys/net/core/rps_sock_flow_entries > /dev/null; then
  echo "Error: Failed to set rps_sock_flow_entries. Please run with sufficient privileges."
  exit 1
fi

# 5. Configure each receive queue.
for i in $(seq 0 $((NUM_QUEUES - 1))); do
  RX_QUEUE="/sys/class/net/$INTERFACE/queues/rx-$i"

  # a) Assign a CPU to this queue (round-robin).
  CPU_INDEX=$((i % NUM_CPUS))
  CPU_BITMAP_HEX=$(printf '%x' $((1 << CPU_INDEX)))
  echo "Assigning CPU $CPU_INDEX (bitmap: $CPU_BITMAP_HEX) to queue rx-$i"
  if ! echo "$CPU_BITMAP_HEX" | sudo tee "$RX_QUEUE/rps_cpus" > /dev/null; then
    echo "Error writing bitmap to $RX_QUEUE/rps_cpus"
    exit 1
  fi

  # b) Set the flow count for this queue.
  echo "Setting flow count for $RX_QUEUE to $RPS_FLOW_CNT_PER_QUEUE"
  if ! echo "$RPS_FLOW_CNT_PER_QUEUE" | sudo tee "$RX_QUEUE/rps_flow_cnt" > /dev/null; then
    echo "Error writing to $RX_QUEUE/rps_flow_cnt"
    exit 1
  fi
done

echo "RPS and RFS configuration updated successfully for $INTERFACE."

המאמרים הבאים