מדריך קלאודפלייר בעברית

תיעוד 261

מודל עקביות

הדף הזה מפרט את מודל העקביות של R2, כולל היכן R2 עקבי באופן חזק וגלובלי ולאילו פעולות זה חל.

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

#מינוח

בהקשר של R2, לעקביות חזקה ולעקביות בסופו של דבר יש המשמעויות הבאות:

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

#פעולות ועקביות

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

פעולהעקביות
קריאה אחרי כתיבה: כתיבה (העלאה) של אובייקט, ואז קריאה שלועקבי באופן חזק: קוראים יראו מיד את האובייקט העדכני באופן גלובלי
מטא-נתונים: עדכון מטא-נתונים של אובייקטעקבי באופן חזק: קוראים יראו מיד את המטא-נתונים המעודכנים באופן גלובלי
מחיקה: מחיקת אובייקטעקבי באופן חזק: קריאות לאותו אובייקט יחזירו מיד שגיאת "does not exist"
רישום אובייקטים: רישום האובייקטים בדליעקבי באופן חזק: פעולת הרישום תרשום את כל האובייקטים בנקודת הזמן הזו
IAM: הוספה או הסרה של הרשאות R2 Storageעקבי בסופו של דבר: למפתח API חדש או מעודכן עשויה לקחת עד דקה עד שההרשאות ישתקפו באופן גלובלי

הערות נוספות:

  • במקרה ששני לקוחות כותבים (PUT או DELETE) לאותו מפתח, הכותב האחרון שמסיים "מנצח".
  • בעת ביצוע העלאה מרובת חלקים, עקביות של קריאה אחרי כתיבה ממשיכה לחול לאחר שכל החלקים הועלו בהצלחה. במקרה שאותו חלק מועלה (בטעות) מכמה כותבים, הכתיבה האחרונה תנצח.
  • העתקת אובייקט בתוך אותו דלי גם עוקבת אחרי אותה עקביות של קריאה אחרי כתיבה כמו כתיבת אובייקט חדש. האובייקט "שהועתק" קריא מיד לכל הלקוחות לאחר שפעולת ההעתקה מסתיימת.
  • כדי למחוק דלי R2, הוא חייב להיות ריק לחלוטין לפני שהמחיקה מותרת. אם תנסו למחוק דלי שעדיין מכיל אובייקטים, תקבלו שגיאה כגון: The bucket you tried to delete (X) is not empty (account Y) או Bucket X cannot be deleted because it isn’t empty. להוראות על ריקון ומחיקה של דלי, ראו מחיקת דליים.

#כתיבות מותנות

R2 מעריך כותרות כתיבה מותנות (לדוגמה If-Match ו-If-None-Match ב-PutObject) באופן אטומי, כחלק מאותה כתיבה שמבצעת commit לאובייקט:

  • התנאי תמיד מוערך מול המצב שבוצע לו commit בדלי ברגע שהכתיבה מבצעת commit, אף פעם לא מול snapshot ישן יותר.
  • כתיבות מותנות מתחרות לאותו מפתח מבוצעות בטור. כאשר שני לקוחות או יותר מנפיקים במקביל PutObject עם If-None-Match: * עבור מפתח שלא היה קיים קודם, לכל היותר בקשה אחת מצליחה וכל בקשה אחרת נכשלת עם שגיאת 412 PreconditionFailed. לכן בטוח להסתמך על If-None-Match: * לסמנטיקה של "create-once": שתי כתיבות מותנות מקבילות לא יכולות שתיהן לראות הצלחה.

לשימוש ב-S3 API, ראו פעולות מותנות ב-PutObject.

#קריאות שליליות וכתיבות שעדיין בדרך

קריאה עקבית באופן חזק (HeadObject או GetObject) שמחזירה NoSuchKey (404) אומרת שהאובייקט לא היה קיים ברגע שהקריאה עובדה. היעדר זה אינו סופי ביחס ל-PutObject מוקדם יותר שהתוצאה שלו עדיין לא ידועה: בקשה שעדיין הייתה בדרך, לדוגמה לקוח שאיבד את החיבור לפני שקיבל את התשובה, עדיין עשויה לבצע commit אחרי שהקריאה השלילית חזרה. קריאות אף פעם אינן מיושנות, אבל הן לא ממתינות לכתיבות מוקדמות יותר ולא מבטלות אותן.

אם אתם צריכים להתייחס לקריאה שלילית כהוכחה שכתיבה נכשלה, קודם ודאו שהכתיבה המקורית הסתיימה באופן סופי (או הצליחה או החזירה שגיאה סופית) לפני שמסתמכים על הקריאה. לחלופין, נסו שוב את הכתיבה עם If-None-Match: *: היא נכשלת עם 412 PreconditionFailed אם הכתיבה העמומה אכן ביצעה commit.

#שמירה במטמון

הערה

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

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

באופן ספציפי, יש לצפות לכך:

  • אובייקט שמוחקים מ-R2, אבל עדיין שמור במטמון, עדיין יהיה זמין. יש לנקות את המטמון אחרי מחיקת אובייקטים אם צריך שהמחיקה הזו תשתקף.
  • כברירת מחדל, המטמון של Cloudflare ישמור תשובות HTTP 404 (Not Found) באופן אוטומטי. אם מעלים אובייקט לאותו נתיב, המטמון עשוי להמשיך להחזיר HTTP 404 עד ש-TTL (Time to Live) של המטמון פג והאובייקט החדש נשלף מ-R2 או המטמון מנוקה.
  • אובייקט עבור מפתח נתון נדרס באובייקט חדש: האובייקט הישן (הקודם) ימשיך להיות מוגש ללקוחות עד ש-TTL של המטמון פג (או שהאובייקט מפונה) או שהמטמון מנוקה.

המטמון לא משפיע על גישה דרך קישורי Worker API או S3 API, כי הפעולות האלה נעשות ישירות מול הדלי ולא עוברות דרך המטמון.