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

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

לתשומת ליבכם

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

  • כדי להחיל את ההגדרות המומלצות שבדף הזה, אתם יכולים להשתמש בשיטות הבאות:

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

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

    • נקודת ביקורת

    • הדרכה

    • הגשה

    • שמירה במטמון של 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 – זיכרון בנפח 448GiB, ללא 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) שמשתמשות במנהל התקן ה-CSI של Cloud Storage FUSE, ההגדרות האלה מנוהלות באופן מלא ומוחלות באופן אוטומטי. במכונות וירטואליות של 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 כדי להבטיח אטומיות. השימוש בקטגוריות עם מרחב שמות היררכי מועיל במיוחד כשיוצרים נקודות ביקורת בקנה מידה גדול, כי מסגרות למידת מכונה משתמשות בשינוי שמות של ספריות כדי לסיים את נקודות הביקורת. זו פקודה אטומית מהירה שנתמכת רק בקטגוריות עם מרחב שמות היררכי. אם אתם לא רוצים להשתמש בקטגוריה עם מרחב שמות היררכי, תוכלו לקרוא את המאמר הגדלת מגבלת שינוי השם לקטגוריות ללא HNS.

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

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

אם אתם רוצים לגשת לספרייה ספציפית בתוך קטגוריה, אתם יכולים לטעון רק את הספרייה הספציפית באמצעות אפשרות הטעינה only-dir במקום לטעון את כל הקטגוריה. כשמבצעים טעינה ספציפית לספרייה, זה מאיץ את הקריאות לרשימה ומפחית את המספר הכולל של הקריאות לרשימה ולנתונים הסטטיסטיים. זה קורה כי מספר הספריות שצריך לעבור בהן כדי לפתור שם קובץ מוגבל, כי קריאות ל-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.5KiB בזיכרון, ובאופן יחסי, המטא-נתונים של מיליון קבצים תופסים בערך 1.5GiB בזיכרון. למידע נוסף, ראו סקירה כללית על שמירה במטמון.

כדי להגדיר את 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

מגדירים את הדגל של מאפיין הנפח gcsfuseMetadataPrefetchOnMount ב-CSI לערך 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 עשויים להשתנות בהתאם לתוכן הקטגוריה ולפריסה ההיררכית, לכן כדאי להגדיר משאבי 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 לשימוש במטמון קבצים ובהורדות במקביל

אפשר לארח את מטמון הקבצים ב-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.

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

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

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

אפשרות 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.

הפעלת קריאות במאגר נתונים זמני (buffer)

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

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

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

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

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

אפשרויות CLI

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

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

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

קובץ תצורה

read:
 enable-buffered-read: true

הגדלת גודל ה-read-ahead של הליבה

בעומסי עבודה שכוללים בעיקר קריאות סדרתיות של קבצים גדולים, כמו הצגה ושחזור של נקודות ביקורת, הגדלת גודל הקריאה מראש יכולה לשפר משמעותית את הביצועים. אפשר לעשות את זה באמצעות הפרמטר read_ahead_kb של ליבת Linux במחשב המקומי. מומלץ להגדיל את הפרמטר read_ahead_kb של הליבה ל-1MB, במקום להשתמש בכמות ברירת המחדל של 128KB שמוגדרת ברוב הפצות Linux. במכונות של 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 לא רלוונטית יותר, והמערכת תתעלם מכל ערך שתספקו. שימו לב שבסביבות של Compute Engine, כדי לנהל את הפרמטר הזה באופן אוטומטי, Cloud Storage FUSE דורש הרשאות sudo ברמה הבסיסית (root) או ללא סיסמה.

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 כולל בדיקות גישה כדי להבטיח את יכולת השחזור של Pods במקרה של הגדרה שגויה של המשתמש בקישורי Workload Identity בין הקטגוריה לחשבון השירות של GKE, שיכולה להגיע למכסות ברירת המחדל של Security Token Service API בקנה מידה נרחב. כדי להשבית את האפשרות הזו, מגדירים את מאפיין הנפח skipCSIBucketAccessCheck של מנהל ההתקן של Persistent Volume CSI. כדי למנוע כשלים בטעינה של ה-Pod, מומלץ לוודא שלחשבון השירות של GKE יש את הרשאת הגישה הנכונה לקטגוריית היעד של Cloud Storage.

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

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

  volumeAttributes:
      - skipCSIBucketAccessCheck: "true"
   

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

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

  • הגדרת דפים ענקיים שקופים לערך 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.

הגדלת מגבלת שינוי השם לקטגוריות שאינן HNS

תמיד כדאי לבצע עומסי עבודה של נקודות בקרה באמצעות קטגוריה שמופעל בה מרחב שמות היררכי, בגלל שינויי שמות אטומיים ומהירים יותר ו-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.

שמירה במטמון של רשימת הליבות (kernel)

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

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

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

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

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

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

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

אפשרות 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) cache, מטמון קומפילציה אופציונלי קבוע שמאחסן פונקציות מקומפלות. כשמשתמשים במטמון הזה, אפשר להאיץ באופן משמעותי את ההרצות הבאות של הסקריפט, כי לא צריך לחזור על שלבי ההידור.

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

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

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

    export JAX_COMPILATION_CACHE_MAX_SIZE=-1
    
  • Ensure checkpoint pod YAML: use the checkpoint configuration for the mountpoint for the JAX JIT cache.

הגדרת Receive Flow Steering‏ (RFS) ל-A4X

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

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

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

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

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

לתשומת ליבכם

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

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

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

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

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

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

#!/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."

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