אימות נתונים וזיהוי שינויים באמצעות סכומי ביקורת

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

מניעת פגיעה בנתונים באמצעות סיכומי ביקורת (checksum)

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

כדי להגן מפני פגיעה בנתונים, ב-Cloud Storage אפשר להשתמש בסיכומי ביקורת (checksum) של CRC32C ו-MD5 כדי לאמת את תקינות הנתונים ולזהות שינויים בנתונים.

‫CRC32C היא שיטת האימות המומלצת לביצוע בדיקות תקינות. אפשר לאמת באמצעות גיבובים מסוג MD5 בהעלאות של קובץ יחיד, אבל לא באובייקטים שמועלים במקטעים, כמו אובייקטים מורכבים ואובייקטים שמועלים באמצעות העלאה מרובת חלקים ב-API בפורמט XML.

סיכומי ביקורת (checksum) לכתיבת נתונים

בכתיבת אובייקטים, הלקוח מחשב את סיכום הביקורת של הקובץ המקומי ומצרף אותו לכותרות ה-HTTP של הבקשה להעלאת האובייקט. השרת מקבל את המטען הייעודי (payload) של הנתונים, מחשב את סיכום הביקורת (checksum) שלו ומאמת את הנתונים על ידי השוואה בין שני סיכומי הביקורת (checksum) לאחר השלמת ההעלאה. אם סיכומי הביקורת תואמים, האובייקט נשמר ב-Cloud Storage יחד עם סיכומי הביקורת שלו. אם סיכומי הביקורת לא תואמים, בקשת הכתיבה תידחה ותוצג השגיאה BadRequestException: 400.

אימות בצד השרת לכתיבת נתונים

Cloud Storage מבצע אימות בצד השרת במקרים הבאים:

העלאות של בקשה אחת (מדיה) ב-API בפורמט JSON

בהעלאות מדיה ב-API בפורמט JSON, אפשר לציין סיכומי ביקורת בכותרת X-Goog-Hash של הבקשה. לדוגמה:

curl -X POST --data-binary @Desktop/dog-pic.jpeg \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: image/jpeg" \
    -H "X-Goog-Hash: crc32c=n03x6A==" \
    "https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=media&name=dog-pic.jpeg"

העלאות מרובות חלקים באמצעות API בפורמט JSON

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

בדוגמה הבאה מצוין סיכום ביקורת (checksum) של CRC32C בחלק של המטא-נתונים של האובייקט בקונטיינר של הבקשה:

--separator_string
Content-Type: application/json; charset=UTF-8

{
"name":"my-document.txt",
"crc32c": "n03x6A=="
}

--separator_string
Content-Type: text/plain

This is a text file.
--separator_string--

בדוגמה הבאה מצוין סיכום ביקורת (checksum) של CRC32C במחרוזת הגבול השלישית של מאגר בקשות:

--separator_string
Content-Type: application/json; charset=UTF-8

{
"name":"my-document.txt"
}

--separator_string
Content-Type: text/plain

This is a text file.

--separator_string
Content-Type: application/json; charset=UTF-8

{ "crc32c": "n03x6A==" }
--separator_string--

העלאות שניתן להמשיך ב-API בפורמט JSON

בהעלאות שניתן להמשיך ב-API בפורמט JSON, אפשר לציין סיכומי ביקורת בכותרת X-Goog-Hash של הבקשה הסופית שמשלימה את ההעלאה. לדוגמה:

curl -i -X PUT --data-binary @Desktop/dog-pic.jpeg \
      -H "Content-Length: 2000000" \
      -H "X-Goog-Hash: crc32c=n03x6A==" \
      "SESSION_URI"

סיכום הביקורת (checksum) שצוין בבקשה הסופית מחושב לפי האובייקט כולו, ולא רק לפי נתוני האובייקט בבקשה הסופית.

העלאות בבקשה אחת באמצעות API בפורמט XML

בהעלאות של בקשה אחת ב-API בפורמט XML, אפשר לציין סיכומי ביקורת בכותרת x-goog-hash של הבקשה.

לדוגמה:

curl -X PUT --data-binary @Desktop/dog-pic.jpeg \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: image/jpeg" \
    -H "x-goog-hash: crc32c=n03x6A==" \
    "https://storage.googleapis.com/my-bucket/dog-pic.jpeg"

בהעלאות בבקשה אחת באמצעות API בפורמט XML אפשר גם להשתמש בכותרת Content-MD5 הרגילה של HTTP. לפרטים, ראו מפרט Content-MD5.

העלאות מרובות חלקים באמצעות API בפורמט XML

בהעלאות מרובות חלקים באמצעות API בפורמט XML, אתם יכולים לציין סיכום ביקורת לכל חלק בהעלאה. כדי לציין סיכום ביקורת (checksum) נפרד לחלק מההעלאה, צריך לכלול את הכותרת x-goog-hash בבקשה לחלק הספציפי הזה.

לדוגמה:

PUT /dog-pic.jpeg?partNumber=1&uploadId=ABgVH8 HTTP/1.1
Host: my-bucket.storage.googleapis.com
Content-Length: 1000000
x-goog-hash: crc32c=n03x6A==

אפשר להשתמש רק בסיכומי ביקורת (checksum) מסוג CRC32C כדי לאמת את התקינות של העלאות מרובות חלקים ב-API בפורמט XML. אין תמיכה בסיכומי ביקורת (checksum) מסוג MD5.

העלאות gRPC

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

בנוסף, gRPC תומך בסיכומי ביקורת (checksum) לכל הודעה. כל הודעת WriteObject מכילה מקטעי נתונים בגודל של עד 2MiB, וכל מקטע יכול לכלול סיכום ביקורת (checksum) משלו. אתם יכולים לציין סיכומי ביקורת לכל הודעה במקום או לצד סיכום ביקורת ברמת האובייקט.

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

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

העתקות ושכתובים ב-Google Cloud CLI

ב-CLI של gcloud, מתבצע אימות אוטומטי של נתונים שמועתקים לקטגוריה של Cloud Storage או ממנה. בפקודות cp,‏ mv ו-rsync, ה-CLI של gcloud משתמש בסיכומי ביקורת (checksum) מסוג MD5 או CRC32C כדי לקבוע אם יש הבדל בין גרסת האובייקט שנמצאת במקור לבין הגרסה שנמצאת ביעד. אם סיכום הביקורת (checksum) של נתוני המקור לא תואם לסיכום הביקורת (checksum) של נתוני היעד, ה-CLI של gcloud ימחק את העותק הלא תקין וידפיס הודעת אזהרה. זה קורה לעיתים רחוקות מאוד. אם זה קורה, צריך לנסות את הפעולה שוב.

האימות האוטומטי מתרחש אחרי שהאובייקט מסתיים, ואובייקטים לא חוקיים גלויים למשך 1-3 שניות לפני שהם מזוהים ונמחקים. בנוסף, יכול להיות שה-CLI של gcloud יופסק אחרי שההעלאה תסתיים אבל לפני שהוא מבצע את האימות, וכך האובייקט הלא תקין יישאר במקומו. אפשר להימנע מהבעיות האלו כשמעלים קבצים בודדים ל-Cloud Storage באמצעות אימות בצד השרת, שמתרחש כשמשתמשים בדגל --content-md5 כדי לציין גיבוב MD5.

‫Google Cloud CLI מתעלם מהדגל --content-md5 לאובייקטים שאין להם גיבוב MD5.

זיהוי שינויים ב-rsync

הפקודה gcloud storage rsync משווה בין סיכומי ביקורת בתרחישים הבאים כדי לקבוע אם לדלג על העברה:

  • המקור והיעד הם קטגוריות של Cloud Storage, ולאובייקט יש סיכום ביקורת (checksum) מסוג MD5 או CRC32C בשתי הקטגוריות.

  • לאובייקט אין זמן שינוי קובץ (mtime) במקור או ביעד.

במקרים שבהם לאובייקט יש ערך mtime גם במקור וגם ביעד, למשל כשהמקור והיעד הם מערכות קבצים, הפקודה rsync משווה בין גודל האובייקטים וערך ה-mtime במקום להשתמש בסיכומי ביקורת (checksums). באופן דומה, אם המקור הוא קטגוריה והיעד הוא מערכת קבצים מקומית, הפקודה rsync משתמשת בזמן היצירה של אובייקט המקור כתחליף ל-mtime, והפקודה לא משתמשת בסיכומי ביקורת.

אם לא זמינים mtime או סיכומי ביקורת, הפקודה rsync משווה רק בין גודלי הקבצים כדי לקבוע אם יש שינוי בין גרסת המקור של האובייקט לבין גרסת היעד. לדוגמה, אי אפשר להשתמש ב-mtime או בסיכומי ביקורת (checksum) כשמשווים בין אובייקטים מורכבים לבין אובייקטים אצל ספק שירותי ענן שלא תומך ב-CRC32C, כי לאובייקטים מורכבים אין סיכומי ביקורת (checksum) של MD5.

אימות בצד הלקוח לכתיבת נתונים

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

בטבלה הבאה מפורטת הגרסה המינימלית של כל לקוח Cloud Storage שתומך בסיכומי ביקורת של כתיבת אובייקטים.

לקוח גרסה שתומכת בסיכומי ביקורת (checksum) של כתיבת אובייקטים
ספריית הלקוח של Cloud Storage עבור ++C ‫2.46 ואילך
ספריית הלקוח של Cloud Storage Go ‫1.60.0 ואילך
ספריית הלקוח של Cloud Storage ב-Java ‫2.62 ואילך
ספריית הלקוח של Cloud Storage ב-Node.js ‫7.19.0 ואילך
ספריית הלקוח של Cloud Storage ב-PHP ‫1.51.0 ואילך
ספריית הלקוח של Cloud Storage ב-Python ‫3.7.0 ואילך
ספריית הלקוח של Cloud Storage ב-Ruby 1.60.0
ספריית הלקוח של Cloud Storage ב-‎ .NET ‫2.3.0 ואילך. מומלץ להשתמש בגרסה 4.15.0, שכוללת אימות של סיכום ביקורת (checksum) בצד השרת.
חיבור ל-Cloud Storage
  • ‫3.0.18 ואילך לחיבור ל-Cloud Storage בגרסה 3.0.x
  • ‫3.1.14 ואילך לגרסה 3.1.x של החיבור ל-Cloud Storage
  • ‫4.0.3 ואילך לחיבור ל-Cloud Storage בגרסה 4.0.x
Cloud Storage FUSE ‫3.8.0 ואילך
Google Cloud CLI

סיכומי ביקורת (checksum) לקריאה ולהורדה של נתונים

בקריאה ובהורדה של אובייקטים, השרת שולח את האובייקט יחד עם סיכום הביקורת (checksum) ששמור בתגובה. הלקוח מחשב את סיכום הביקורת (checksum) של הקובץ שנקרא או הורד על סמך הבייטים שקיבל, ומשווה בין שני סיכומי הביקורת כדי לאמת את תקינות הנתונים.

אימות בצד הלקוח לקריאה ולהורדה

כברירת מחדל, כל ערכות ה-SDK של ספריות הלקוח של Cloud Storage תומכות בחישוב סיכומי ביקורת (checksum) להורדות ולקריאות של אובייקטים. בטבלה הבאה מוסבר איך להשבית את ההורדה של אובייקטים או את קריאת סיכומי הביקורת בכל SDK של ספריית לקוח.

ספריית לקוח הוראות להשבתת סיכומי ביקורת (checksum) של קריאה או הורדה של אובייקטים
ספריית הלקוח של Cloud Storage עבור ++C בספריית הלקוח של C++‎, משביתים את אימות סיכום הביקורת על ידי הגדרת DownloadChecksumValidationOption לערך ChecksumAlgorithm::kNone.
ספריית הלקוח של Cloud Storage Go בספריית הלקוח של Go, משביתים את אימות סיכום הביקורת (checksum) על ידי ציון אפשרויות קורא בזמן האתחול. צריך להעביר את הערך WithDisableReaderChecksum() כשקוראים לפונקציה NewReader או את הערך WithDisableMRDReadChecksum() כשקוראים לפונקציה NewMultiRangeDownloader.
ספריית הלקוח של Cloud Storage ב-Java כדי להשבית את האימות הפנימי של סיכום הביקורת (checksum) של CRC32C בנתיבי קריאה בספריית הלקוח של Java, מעבירים את מאפיין המערכת של JVM‏ -Dcom.google.cloud.storage.Hasher.read=disabled, שמשבית את ה-hasher הפנימי לקריאות. אם רוצים להשבית את סיכום הביקורת באופן גלובלי גם בקריאה וגם בכתיבה, צריך להשתמש ב--Dcom.google.cloud.storage.Hasher.default=disabled.
ספריית הלקוח של Cloud Storage ב-Node.js בספריית הלקוח של Node.js, משביתים את אימות סיכום הביקורת (checksum) על ידי העברת { validation: false } בתוך אובייקט אפשרות ההגדרה שסופק להפעלות של שיטת ההורדה.
ספריית הלקוח של Cloud Storage ב-PHP בספריית הלקוח של PHP, משביתים את אימות סיכום הביקורת גם בנתיבי הקריאה של ה-API בפורמט JSON וגם בנתיבי הקריאה של ה-API בפורמט XML. כדי לעשות את זה, מעבירים את 'validate' => false או את 'validate' => 'none' בתוך מערך האפשרויות המשויך ($options['validate']) כשקוראים ל-methods של ההורדה.
ספריית הלקוח של Cloud Storage ב-Python בספריית הלקוח של Python, השבתת האימות של סיכום הביקורת תלויה בהעברה של הלקוח: ללקוח JSON, מעבירים את checksum=None (נתמך ב-methods כמו download_to_file), וללקוח gRPC, מגדירים את enable_checksum=False.
ספריית הלקוח של Cloud Storage ב-Ruby בספריית הלקוח של Ruby, משביתים את אימות סיכום הביקורת על ידי העברת ארגומנטים של מילות מפתח (checksum: או verify:) ישירות לשיטות ההורדה, ובאופן ספציפי מגדירים את verify: none או את verify: false.
ספריית הלקוח של Cloud Storage ב-‎ .NET בספריית הלקוח של ‎ .NET, משביתים את אימות סיכום הביקורת על ידי הגדרת המאפיין ChecksumValidation לערך DownloadValidationMode.Never באובייקט DownloadObjectOptions שמועבר לקריאות ל-method של ההורדה.

ביצוע בדיקות של תקינות הנתונים באובייקטים שהורדו או נקראו

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

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

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

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

  • תגובה שמכילה רק חלק מנתוני האובייקט: סוג התגובה הזה מתרחש בבקשות Range.

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

    אם האפליקציה צריכה לקרוא טווחי אובייקטים במקום אובייקטים מלאים בבת אחת, מומלץ להשתמש ב-gRPC. אחרת, מומלץ לשלוח בקשות לטווח חלקי של אובייקט רק כדי להפעיל מחדש את ההורדה של אובייקט שלם אחרי ההיסט האחרון שהתקבל, כי במקרה כזה אפשר לחשב ולאמת את סיכום הביקורת (checksum) כשההורדה המלאה מסתיימת.

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

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