העלאות דרך API

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

אפשרויות העלאה

ממשק BigQuery API מאפשר להעלות סוגים מסוימים של נתונים בינאריים או מדיה. המאפיינים הספציפיים של הנתונים שאפשר להעלות מפורטים בדף העזר של כל שיטה שתומכת בהעלאות של מדיה:

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

אפשר לשלוח בקשות העלאה בדרכים הבאות. מציינים את ה-method שבה משתמשים באמצעות פרמטר הבקשה uploadType.

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

כשמעלים מדיה, משתמשים ב-URI מיוחד. למעשה, לשיטות שתומכות בהעלאות של מדיה יש שתי נקודות קצה של URI:

  • מזהה ה-URI של ההעלאה, /upload, עבור המדיה. הפורמט של נקודת הקצה להעלאה הוא ה-URI הסטנדרטי של המשאב עם הקידומת '/upload'. משתמשים ב-URI הזה כשמעבירים את נתוני המדיה עצמם.

    לדוגמה: POST /upload/bigquery/v2/projects/projectId/jobs

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

    דוגמה: POST /bigquery/v2/projects/projectId/jobs

העלאה מרובת חלקים

אם יש לכם מטא-נתונים שאתם רוצים לשלוח יחד עם הנתונים להעלאה, אתם יכולים לשלוח בקשת multipart/related אחת. האפשרות הזו מתאימה אם הנתונים שאתם שולחים קטנים מספיק כדי שאפשר יהיה להעלות אותם שוב בשלמותם אם החיבור ייכשל.

כדי להשתמש בהעלאה מרובת חלקים, שולחים בקשת POST ל-URI של השיטה /upload ומוסיפים את פרמטר השאילתה uploadType=multipart, לדוגמה:

POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart

כותרות ה-HTTP ברמה העליונה שבהן צריך להשתמש כשיוצרים בקשת העלאה מרובת חלקים כוללות:

  • Content-Type. מגדירים את הערך multipart/related וכוללים את מחרוזת הגבול שבה משתמשים כדי לזהות את חלקי הבקשה.
  • Content-Length. הערך שמוגדר הוא המספר הכולל של הבייטים בגוף הבקשה. חלק המדיה בבקשה צריך להיות קטן מגודל הקובץ המקסימלי שצוין לשיטה הזו.

גוף הבקשה מעוצב כסוג תוכן multipart/related [RFC2387] ומכיל בדיוק שני חלקים. החלקים מזוהים על ידי מחרוזת גבולות, ואחרי מחרוזת הגבולות האחרונה מופיעים שני מקפים.

לכל חלק בבקשת ה-multipart צריך להוסיף כותרת Content-Type:

  1. חלק המטא-נתונים: צריך להופיע ראשון, וContent-Type חייב להיות זהה לאחד מפורמטי המטא-נתונים המקובלים.
  2. קטע מדיה: צריך להופיע שני, ו-Content-Type חייב להתאים לאחד מסוגי ה-MIME של המדיה שהשיטה מקבלת.

בהפניה ל-API מפורטת רשימה של סוגי MIME של מדיה שמתקבלים ומגבלות הגודל של קבצים להעלאה לכל שיטה.

הערה: כדי ליצור או לעדכן רק את חלק המטא-נתונים, בלי להעלות את הנתונים המשויכים, פשוט שולחים בקשת POST או PUT לנקודת הקצה של המשאב הרגיל: https://www.googleapis.com/bigquery/v2/projects/projectId/jobs

דוגמה: העלאה מרובת חלקים

בדוגמה הבאה מוצגת בקשת העלאה מרובת חלקים ל-BigQuery API.

POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

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

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}


--foo_bar_baz
Content-Type: */*

CSV, JSON, AVRO, PARQUET, or ORC data
--foo_bar_baz--

אם הבקשה תתבצע בהצלחה, השרת יחזיר את קוד הסטטוס 200 OK של HTTP יחד עם המטא-נתונים:

HTTP/1.1 200
Content-Type: application/json

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

העלאה שניתן להמשיך

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

השלבים לשימוש בהעלאה שניתן להמשיך אותה כוללים:

  1. התחלת סשן שניתן להמשיך. שולחים בקשה ראשונית למזהה ה-URI של ההעלאה, כולל המטא-נתונים, אם יש.
  2. שומרים את ה-URI של הסשן שניתן להמשיך. שומרים את ה-URI של הסשן שמוחזר בתשובה לבקשה הראשונית. תשתמשו בו בשאר הבקשות בסשן הזה.
  3. מעלים את הקובץ. שולחים את קובץ המדיה אל ה-URI של הסשן שניתן להמשיך.

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

הערה: תוקף של URI להעלאה הוא שבוע.

שלב 1: מתחילים סשן שניתן להמשיך

כדי להתחיל העלאה שניתן להמשיך, שולחים בקשת POST ל-URI של השיטה /upload ומוסיפים את פרמטר השאילתה uploadType=resumable, לדוגמה:

POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable

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

משתמשים בכותרות ה-HTTP הבאות עם הבקשה הראשונית:

  • X-Upload-Content-Type. מגדירים את סוג ה-MIME של המדיה של נתוני ההעלאה שיועברו בבקשות הבאות.
  • X-Upload-Content-Length. הערך שמוגדר הוא מספר הבייטים של נתוני ההעלאה שיועברו בבקשות הבאות.  אם אורך הסרטון לא ידוע בזמן שליחת הבקשה, אפשר להשמיט את הכותרת הזו.
  • אם מספקים מטא-נתונים: Content-Type. ההגדרה מתבצעת בהתאם לסוג הנתונים של המטא-נתונים.
  • Content-Length. הערך שמוגדר הוא מספר הבייטים שצוין בגוף הבקשה הראשונית הזו. זה לא נדרש אם משתמשים בקידוד העברה במקטעים.

בהפניה ל-API מפורטת רשימה של סוגי MIME של מדיה שמתקבלים ומגבלות הגודל של קבצים להעלאה לכל שיטה.

דוגמה: בקשה להתחלת סשן שניתן להמשיך

בדוגמה הבאה מוצג איך מתחילים סשן שאפשר להמשיך אותו ב-BigQuery API.

POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: */*
X-Upload-Content-Length: 2000000

{
  "configuration": {
    "load": {
      "sourceFormat": "NEWLINE_DELIMITED_JSON",
      "schema": {
        "fields": [
          {"name": "f1", "type": "STRING"},
          {"name": "f2", "type": "INTEGER"}
        ]
      },
      "destinationTable": {
        "projectId": "projectId",
        "datasetId": "datasetId",
        "tableId": "tableId"
      }
    }
  }
}

הערה: אם שולחים בקשת עדכון ראשונית שאפשר להמשיך אותה בלי מטא-נתונים, צריך להשאיר את גוף הבקשה ריק ולהגדיר את הכותרת Content-Length לערך 0.

בקטע הבא מוסבר איך לטפל בתגובה.

שלב 2: שומרים את ה-URI של הסשן שניתן להמשיך

אם בקשת פתיחת הסשן מצליחה, שרת ה-API מגיב עם קוד סטטוס 200 OK HTTP. בנוסף, היא מספקת כותרת Location שמציינת את ה-URI של הסשן שניתן להמשיך. הכותרת Location, שמוצגת בדוגמה שלמטה, כוללת חלק של פרמטר שאילתה upload_id שמספק את מזהה ההעלאה הייחודי שבו צריך להשתמש בסשן הזה.

דוגמה: תגובה להתחלת סשן שניתן להמשיך

זו התשובה לבקשה משלב 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

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

מעתיקים ושומרים את ה-URI של הסשן כדי להשתמש בו בבקשות הבאות.

שלב 3: העלאת הקובץ

כדי להעלות את הקובץ, שולחים בקשת PUT אל ה-URI של ההעלאה שקיבלתם בשלב הקודם. הפורמט של בקשת ההעלאה הוא:

PUT session_uri

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

דוגמה: בקשה להעלאת קובץ שניתן להמשיך

זוהי בקשה להעלאה של קובץ CSV,‏ JSON,‏ AVRO,‏ PARQUET או ORC בגודל 2,000,000 בייט, שאפשר להשהות ולחדש את ההעלאה שלו, בדוגמה הנוכחית.

PUT https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: */*

bytes 0-1999999

אם הבקשה מצליחה, השרת ישיב עם HTTP 201 Created, יחד עם המטא-נתונים שמשויכים למשאב הזה. אם הבקשה הראשונית של הסשן שניתן להמשך הייתה PUT, כדי לעדכן משאב קיים, תשובת ההצלחה תהיה 200 OK, יחד עם המטא-נתונים שמשויכים למשאב הזה.

אם בקשת ההעלאה הופסקה או אם מקבלים תשובה מסוג HTTP 503 Service Unavailable או כל תשובה אחרת מסוג 5xx מהשרת, אפשר להיעזר בהוראות שבקטע המשך של העלאה שהופסקה.  


העלאת הקובץ במקטעי נתונים

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


המשך העלאה שהופסקה

אם בקשת העלאה הופסקה לפני קבלת תשובה, או אם מקבלים מהשרת תשובה של HTTP 503 Service Unavailable, צריך להמשיך את ההעלאה מהמקום שבו היא הופסקה. לשם כך:

  1. סטטוס הבקשה שליחת בקשת PUT ריקה למזהה ה-URI של ההעלאה כדי לברר את הסטטוס הנוכחי של ההעלאה. בבקשה הזו, כותרות ה-HTTP צריכות לכלול כותרת Content-Range שמציינת שהמיקום הנוכחי בקובץ לא ידוע.  לדוגמה, אם האורך הכולל של הקובץ הוא 2,000,000, מגדירים את Content-Range ל-*/2000000. אם אתם לא יודעים מה הגודל המלא של הקובץ, צריך להגדיר את Content-Range ל-*/*.

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

  2. אחזור מספר הבייטים שהועלו מעבדים את התגובה משאילתת הסטטוס. השרת משתמש בכותרת Range בתגובה שלו כדי לציין אילו בייטים הוא קיבל עד עכשיו.  לדוגמה, כותרת Range של 0-299999 מציינת ש-300,000 הבייטים הראשונים של הקובץ התקבלו.
  3. מעלים את הנתונים שנותרו. לבסוף, אחרי שאתם יודעים איפה צריך להמשיך את הבקשה, שולחים את הנתונים שנותרו או את המקטע הנוכחי. שימו לב: בשני המקרים, צריך להתייחס לנתונים שנותרו כאל נתח נפרד, ולכן צריך לשלוח את הכותרת Content-Range כשממשיכים את ההעלאה.
דוגמה: המשך העלאה שהופסקה

‫1) שולחים בקשה לסטטוס ההעלאה.

הבקשה הבאה משתמשת בכותרת Content-Range כדי לציין שהמיקום הנוכחי בקובץ בגודל 2,000,000 בייט לא ידוע.

PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */2000000

‫2) חילוץ מספר הבייטים שהועלו עד עכשיו מהתגובה.

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

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42

הערה: יכול להיות שהתגובה לסטטוס תהיה 201 Created או 200 OK אם ההעלאה הושלמה. זה יכול לקרות אם החיבור נותק אחרי שכל הבייטים הועלו אבל לפני שהלקוח קיבל תגובה מהשרת.

‫3) ממשיכים את ההעלאה מהנקודה שבה היא הופסקה.

הבקשה הבאה ממשיכה את ההעלאה על ידי שליחת הבייטים שנותרו בקובץ, החל מבייט 43.

PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

שיטות מומלצות

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

  • אפשר להמשיך או לנסות שוב להעלות קבצים שנכשלו בגלל שיבושים בחיבור או בגלל שגיאות מסוג 5xx, כולל:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • אם מוחזרת שגיאת שרת 5xx כלשהי כשממשיכים או מנסים שוב להעלות בקשות, צריך להשתמש באסטרטגיית השהיה מעריכית לפני ניסיון חוזר. השגיאות האלה יכולות להופיע אם יש עומס יתר על השרת. השהיה מעריכית לפני ניסיון חוזר (exponential backoff) יכולה לעזור להקל על בעיות כאלה בתקופות של נפח גדול של בקשות או עומס תנועה ברשת.
  • בקשות מסוגים אחרים לא צריכות להיות מטופלות באמצעות השהיה מעריכית לפני ניסיון חוזר, אבל עדיין אפשר לנסות לשלוח חלק מהן שוב. כשמנסים לשלוח מחדש את הבקשות האלה, כדאי להגביל את מספר הניסיונות. לדוגמה, הקוד יכול להגביל את מספר הניסיונות החוזרים לעשרה או פחות לפני דיווח על שגיאה.
  • כדי לטפל בשגיאות 404 Not Found ו-410 Gone כשמבצעים העלאות שניתן להמשיך, צריך להתחיל מחדש את כל ההעלאה.

השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

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

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

התהליך להטמעה של השהיה מעריכית פשוטה לפני ניסיון חוזר הוא כזה:

  1. שולחים בקשה ל-API.
  2. מקבלים תגובה HTTP 503, שמציינת שצריך לנסות שוב לשלוח את הבקשה.
  3. ממתינים שנייה אחת + מספר אקראי של אלפיות השנייה ומנסים לשלוח שוב את הבקשה.
  4. מקבלים תגובה HTTP 503, שמציינת שצריך לנסות שוב לשלוח את הבקשה.
  5. ממתינים 2 שניות + מספר אקראי של אלפיות השנייה, ואז מנסים לשלוח שוב את הבקשה.
  6. מקבלים תגובה HTTP 503, שמציינת שצריך לנסות שוב לשלוח את הבקשה.
  7. ממתינים 4 שניות + מספר אקראי של אלפיות השנייה, ומנסים לשלוח שוב את הבקשה.
  8. מקבלים תגובה HTTP 503, שמציינת שצריך לנסות שוב לשלוח את הבקשה.
  9. ממתינים 8 שניות + מספר אקראי של אלפיות השנייה, ומנסים לשלוח שוב את הבקשה.
  10. מקבלים תגובה HTTP 503, שמציינת שצריך לנסות שוב לשלוח את הבקשה.
  11. ממתינים 16 שניות + מספר אקראי של אלפיות השנייה, ומנסים לשלוח שוב את הבקשה.
  12. תפסיק. דיווח על שגיאה או רישום שלה ביומן.

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

הערה: זמן ההמתנה הוא תמיד (2 בחזקת n) + מספר אקראי במילישניות, כאשר n הוא מספר שלם שעולה באופן מונוטוני ומוגדר בהתחלה כ-0. המספר השלם n גדל ב-1 בכל איטרציה (כל בקשה).

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

מדריכים לספריות לקוח של API