BigQuery Storage Write API 簡介

BigQuery Storage Write API 是適用於 BigQuery 的整合式資料擷取 API,將串流內容擷取和批次載入功能合併為單一的高效能 API。您可以使用 Storage Write API,將記錄即時串流至 BigQuery,或批次處理任意大量記錄,並在單一原子作業中提交這些記錄。

使用 Storage Write API 的好處

「僅傳送一次」傳送語意。Storage Write API 透過使用串流偏移量,支援「一次性」語意。與 tabledata.insertAll 方法不同,如果用戶端在附加記錄時提供串流偏移量,Storage Write API 絕不會在串流中寫入兩個偏移量相同的訊息。

串流層級交易。您可以將資料寫入串流,並將資料提交為單一交易。如果提交作業失敗,您可以放心重試該作業。

跨串流的交易。多個 worker 可以建立各自的串流,以便獨立處理資料。所有 worker 完成後,您可以將所有串流做為交易提交。

高效的通訊協定。Storage Write API 比舊版 insertAll 方法更有效率,因為它使用的是 gRPC 串流,而非透過 HTTP 的 REST。Storage Write API 也支援 protocol buffer 二進位格式和 Apache Arrow 資料欄格式,這些格式比 JSON 更有效率。寫入要求為非同步,且保證順序。

偵測結構定義更新。如果在用戶端串流期間,基礎資料表結構定義發生變更,Storage Write API 會通知用戶端。用戶端可以決定是否要使用更新的結構定義重新連線,或繼續寫入現有的連線。

降低成本。Storage Write API 的費用比舊版 insertAll 串流 API 低得多。此外,您每個月最多可免費攝入 2 TiB 的資料。

所需權限

如要使用 Storage Write API,您必須具備 bigquery.tables.updateData 權限。

以下是包含 bigquery.tables.updateData 權限的預先定義 Identity and Access Management (IAM) 角色:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

如要進一步瞭解 BigQuery 中的 IAM 角色和權限,請參閱「預先定義的角色與權限」一文。

驗證範圍

如要使用 Storage Write API,您必須擁有下列其中一種 OAuth 範圍:

  • https://www.googleapis.com/auth/bigquery
  • https://www.googleapis.com/auth/cloud-platform
  • https://www.googleapis.com/auth/bigquery.insertdata

詳情請參閱驗證總覽一文。

Storage Write API 總覽

Storage Write API 中的核心抽象概念是串流。串流會將資料寫入 BigQuery 資料表。多個資料流可以同時寫入相同的資料表。

預設串流

Storage Write API 提供預設串流,適用於持續接收資料的串流情境。其具有以下特性:

  • 寫入預設資料流的資料可立即供查詢。
  • 預設串流支援至少一次語意。
  • 您不需要明確建立預設串流。

如果您要從舊版 tabledata.insertall API 遷移,請考慮使用預設串流。它具有類似的寫入語意,但資料復原能力更強,且縮放限制較少。

API 流程:

  1. AppendRows (迴圈)

如需更多資訊和程式碼範例,請參閱「使用預設串流來處理至少一次語義」。

應用程式建立的串流

如果您需要下列任一行為,可以明確建立串流:

  • 透過使用串流偏移量,實現「僅限一次」寫入語意。
  • 支援其他 ACID 屬性。

一般來說,應用程式建立的串流可讓您更精確地控管功能,但代價是增加複雜度。

建立串流時,您必須指定類型。這類型會控制寫入串流的資料何時會在 BigQuery 中顯示,供讀取。

待處理類型

待處理類型中,記錄會處於待處理狀態,直到您提交資料流為止。當您提交串流時,所有待處理資料都會開放供讀取。修訂作業是不可分割的作業。請將此類型用於批次工作負載,做為 BigQuery 載入工作的替代方案。詳情請參閱「使用 Storage Write API 批次載入資料」。

API 流程:

  1. CreateWriteStream
  2. AppendRows (迴圈)
  3. FinalizeWriteStream
  4. BatchCommitWriteStreams

已提交的類型

已提交類型中,您寫入資料流的記錄會立即可供讀取。請將這類型用於需要最小讀取延遲的串流工作負載。預設串流會使用已提交類型的至少一次表單。詳情請參閱「使用已提交類型來實現精確一次的語義」。

API 流程:

  1. CreateWriteStream
  2. AppendRows (迴圈)
  3. FinalizeWriteStream (選填)

緩衝類型

緩衝型別是進階型別,一般不應使用,除非搭配使用 Apache Beam BigQuery I/O 連接器。如果您有小批次資料,且想確保這些資料會一併顯示,請使用已提交類型,並在單一要求中傳送每個批次。在這種情況下,系統會提供資料列層級的提交作業,並將記錄緩衝,直到透過清除資料流來提交資料列為止。

API 流程:

  1. CreateWriteStream
  2. AppendRowsFlushRows (循環)
  3. FinalizeWriteStream (選填)

選取類型

請參考下列流程圖,判斷哪種類型最適合您的工作負載:

圖片

API 詳細資料

使用 Storage Write API 時,請考量以下事項:

AppendRows

AppendRows 方法會將一或多筆記錄附加至資料流。第一次呼叫 AppendRows 時,必須包含串流名稱和資料結構定義,並指定為 DescriptorProto。或者,如果您以 Apache Arrow 格式擷取資料,可以在第一次呼叫 AppendRows 時新增序列化的箭頭架構。最佳做法是在每個 AppendRows 呼叫中傳送一批資料列。請勿一次傳送一列。

Proto 緩衝區處理

通訊協定緩衝區提供一種語言中立、平台中立和可擴充的機制,可以向前相容和向後相容的方式序列化結構化資料。這些檔案的優點在於,可提供精簡的資料儲存空間,並以快速且有效率的方式進行剖析。如要進一步瞭解通訊協定緩衝區,請參閱「通訊協定緩衝區總覽」。

如果您打算直接使用預先定義的通訊協定緩衝區訊息來使用 API,通訊協定緩衝區訊息就無法使用 package 指定符,且所有巢狀或列舉類型都必須在頂層根訊息中定義。不得參照外部訊息。如需範例,請參閱 sample_data.proto

Java 和 Go 用戶端支援任意通訊協定緩衝區,因為用戶端程式庫會將通訊協定緩衝區結構化。

Apache Arrow 處理

如要提供意見回饋或要求支援這項功能,請來信至 [email protected]。Apache Arrow 是通用的資料欄格式,也是用於資料處理的多語言工具箱。Apache Arrow 提供不受語言限制的資料欄導向記憶體格式,可用於處理平面和階層式資料,並可在最新硬體上進行高效的分析作業。如要進一步瞭解 Apache Arrow,請參閱「Apache Arrow」。Storage Write API 支援使用 AppendRowsRequest 類別中的序列化箭頭架構和資料,擷取箭頭資料。Python 用戶端程式庫內建 Apache Arrow 攝入功能。其他語言可能需要呼叫原始的 AppendRows API,才能以 Apache Arrow 格式擷取資料。

FinalizeWriteStream

FinalizeWriteStream 方法會將串流定稿,因此無法附加任何新資料。此方法在 Pending 類型中為必要方法,在 CommittedBuffered 類型中則為選用方法。預設串流不支援這個方法。

處理錯誤

如果發生錯誤,傳回的 google.rpc.Status 可能會在錯誤詳細資料中包含 StorageError。請查看 StorageErrorCode,找出特定錯誤類型。如要進一步瞭解 Google API 錯誤模型,請參閱「錯誤」。

連線

Storage Write API 是使用雙向連線的 gRPC API。AppendRows 方法會建立與串流的連線。您可以在預設串流上開啟多個連線。這些附加作業是異步的,可讓您同時傳送一系列寫入作業。每個雙向連線的回應訊息會依照要求傳送的順序傳送。

應用程式建立的串流只能有一個有效連線。最佳做法是限制有效連線數量,並盡可能使用單一連線寫入大量資料。在 Java 或 Go 中使用預設串流時,您可以使用 Storage Write API 多工處理功能,透過共用連線寫入多個目的地資料表。

一般而言,單一連線支援的傳輸量至少為 1 MBps。上限取決於多項因素,例如網路頻寬、資料結構定義和伺服器負載。連線達到吞吐量上限時,系統可能會拒絕或排入佇列的傳入要求,直到執行中的要求數量減少為止。如果需要更高的處理量,請建立更多連線。

如果連線閒置太久,BigQuery 就會關閉 gRPC 連線。如果發生這種情況,回應代碼會是 HTTP 409。在伺服器重新啟動或其他情況下,gRPC 連線也可能會關閉。如果發生連線錯誤,請建立新的連線。如果連線關閉,Java 和 Go 用戶端程式庫會自動重新連線。

用戶端程式庫支援

儲存空間寫入 API 的用戶端程式庫採用多種程式設計語言,並提供基礎的 gRPC 架構 API。這個 API 會運用雙向串流等進階功能,因此可能需要額外的開發工作才能支援。為此,這個 API 提供許多較高層級的抽象概念,可簡化這些互動並減少開發人員的疑慮。建議您盡可能使用其他程式庫抽象化。

本節將進一步說明開發人員可使用的語言和程式庫,這些語言和程式庫可提供產生的 API 以外的其他功能。

如要查看與 Storage Write API 相關的程式碼範例,請參閱「所有 BigQuery 程式碼範例」。

Java 用戶端

Java 用戶端程式庫提供兩個寫入器物件:

  • StreamWriter:接受通訊協定緩衝區格式的資料。

  • JsonStreamWriter:接受 JSON 格式的資料,並將其轉換為通訊協定緩衝區,再透過網路傳送。JsonStreamWriter 也支援自動結構定義更新。如果資料表結構定義有所變更,寫入器會自動重新連結至新結構定義,讓用戶端可使用新結構定義傳送資料。

兩種寫入器的程式設計模式相似。主要差異在於您如何格式化酬載。

writer 物件會管理 Storage Write API 連線。寫入器物件會自動清理要求、在要求中加入區域轉送標頭,並在發生連線錯誤後重新連線。如果直接使用 gRPC API,您必須處理這些詳細資料。

Go 用戶端

Go 用戶端會使用用戶端-伺服器架構,以 proto2 編碼通訊協定緩衝區格式的訊息。如要進一步瞭解如何使用 Go 用戶端,請參閱Go 說明文件,其中提供範例程式碼。

Python 用戶端

Python 用戶端是包裝 gRPC API 的低階用戶端。如要使用這個用戶端,您必須按照指定類型的 API 流程,以通訊協定緩衝區的形式傳送資料。

避免在 Python 中使用動態 Proto 訊息產生功能,因為該程式庫的效能不佳。

如要進一步瞭解如何在 Python 中使用通訊協定緩衝區,請參閱 Python 教學課程中的通訊協定緩衝區基本概念

您也可以使用 Apache Arrow 攝入格式,做為使用 Storage Write API 攝入資料的替代通訊協定。詳情請參閱「使用 Apache Arrow 格式擷取資料」。

NodeJS 用戶端

NodeJS 用戶端程式庫可接受 JSON 輸入內容,並提供自動重新連線支援功能。如要進一步瞭解如何使用用戶端,請參閱說明文件

處理無法使用

使用指數輪詢機制重試可減少隨機錯誤和服務短暫中斷的情況,但為了避免在服務中斷一段時間後刪除資料列,您必須多加思索。特別是,如果客戶持續無法插入資料列,該怎麼做?

答案取決於您的需求。舉例來說,如果 BigQuery 用於營運分析,且允許部分資料列遺失,則用戶端可以在重試幾次後放棄並捨棄資料。相反地,如果每個資料列對業務至關重要 (例如金融資料),則您需要採用策略來保留資料,直到日後可插入資料為止。

處理持續性錯誤的常見方法之一,就是將資料列發布至 Pub/Sub 主題,以利日後評估及可能的插入作業。另一個常見的方法是暫時在用戶端上保存資料。這兩種方法都能讓用戶端保持未封鎖狀態,同時確保可在可用性恢復後插入所有資料列。

時間單位資料欄分區

您可以將資料串流至以 DATEDATETIMETIMESTAMP 欄分區的資料表,該欄的資料範圍為過去 10 年至未來 1 年。超出這個範圍的資料會遭到拒絕。

資料進行串流時,一開始會置於 __UNPARTITIONED__ 分區。收集到足夠的未分區資料後,BigQuery 就會重新分區資料,並將資料放入適當的分區。不過,沒有服務水準協議 (SLA) 定義資料從 __UNPARTITIONED__ 區隔移出所需的時間。

Storage Write API 不支援使用區隔裝飾器

Fluent Bit Storage Write API 輸出外掛程式

Fluent Bit Storage Write API 輸出外掛程式可自動將 JSON 記錄擷取至 BigQuery,因此您不必編寫程式碼。使用這個外掛程式時,您只需設定相容的輸入外掛程式,並設定設定檔,即可開始串流資料。Fluent Bit 是開放原始碼和跨平台的記錄處理器和轉送器,可使用輸入和輸出外掛程式處理不同類型的資料來源和接收器。

這個外掛程式支援下列功能:

  • 使用預設類型的至少一次語意。
  • 使用已提交類型的「僅限一次」語意。
  • 當顯示回壓時,針對預設串流進行動態調整。

Storage Write API 專案指標

如要瞭解如何透過 Storage Write API 監控資料攝入作業,例如伺服器端要求層級延遲時間、並行連線、上傳位元組和上傳資料列,請參閱 Google Cloud 指標

使用資料操縱語言 (DML) 搭配最近串流的資料

您可以使用資料操控語言 (DML),例如 UPDATEDELETEMERGE 陳述式,修改 BigQuery Storage Write API 最近寫入 BigQuery 資料表的資料列。最近的寫入作業是指過去 30 分鐘內發生的寫入作業。

如要進一步瞭解如何使用 DML 修改串流資料,請參閱「使用資料操縱語言」。

限制

  • 針對最近串流的資料執行 DML 陳述式變異功能的支援,不適用於使用 BigQuery Storage Write API 緩衝型別串流的資料
  • 針對最近串流的資料執行 DML 變異陳述式的支援功能,不適用於使用 insertAll streaming API 串流的資料。
  • 系統不支援在多陳述式交易中,針對最近串流的資料執行變異 DML 陳述式。

Storage Write API 配額

如要瞭解 Storage Write API 配額和限制,請參閱 BigQuery Storage Write API 配額與限制

您可以在 Google Cloud 控制台的「配額」頁面中,監控並瞭解並行連線和傳輸量配額的用量。

計算處理量

假設您的目標是從 1 億個端點收集記錄,每分鐘產生 1,500 個記錄。接著,您可以將吞吐量估算為 100 million * 1,500 / 60 seconds = 2.5 GB per second。您必須事先確保有足夠的配額,才能提供這項吞吐量。

Storage Write API 定價

如需定價資訊,請參閱「資料擷取定價」。

用途範例

假設有一個管道處理端點記錄中的事件資料。事件會持續產生,因此必須盡快在 BigQuery 中查詢。由於資料新鮮度對此用途至關重要,因此 Storage Write API 是將資料擷取至 BigQuery 的最佳選擇。建議的架構是將事件傳送至 Pub/Sub,讓串流 Dataflow 管道直接將事件串流至 BigQuery。

這個架構的主要可靠性問題,是如何處理無法將記錄插入 BigQuery 的情況。如果每個記錄都很重要且不能遺失,則需要先緩衝資料,再嘗試插入。在上述建議架構中,Pub/Sub 可透過訊息保留功能扮演緩衝區的角色。應將 Dataflow 管道設為使用截斷的指數回退,重試 BigQuery 串流插入作業。當 Pub/Sub 的緩衝區容量用盡時 (例如 BigQuery 長時間無法使用或網路故障),資料就必須儲存在用戶端上,而用戶端需要一種機制,在可用性恢復後恢復插入已儲存的記錄。如要進一步瞭解如何處理這種情況,請參閱 Google Pub/Sub 可靠性指南網誌文章。

另一個要處理的失敗案例是毒性記錄。毒死記錄是指 BigQuery 拒絕的記錄,因為該記錄無法插入,且發生無法重試的錯誤,或是在重試次數達到上限後,仍未成功插入的記錄。這兩種記錄類型都應由 Dataflow 管道儲存在「死信佇列」中,以利進一步調查。

如果需要確切一次語義,請使用已提交類型建立寫入串流,並使用用戶端提供的記錄偏移量。這樣一來就能避免重複,因為只有在偏移值與下一個附加偏移值相符時,系統才會執行寫入作業。不提供偏移量,表示記錄會附加至串流的目前結尾,而重試失敗的附加作業可能會導致記錄在串流中出現多次。

如果不需要確保一次一筆的保證,寫入預設串流可提供更高的總處理量,且不會影響建立寫入串流的配額限制

預估聯播網的總處理量,並事先確認您有足夠的配額來放送總處理量。

如果工作負載以非常不均衡的速度產生或處理資料,請嘗試平滑處理用戶端的任何負載尖峰,並以固定的吞吐量串流至 BigQuery。這麼做可簡化處理能力規劃。如果無法做到這點,請務必準備好在短暫的尖峰期間,處理吞吐量超過配額的 429 (資源耗盡) 錯誤。

如需使用 Storage Write API 的詳細範例,請參閱「使用 Storage Write API 串流資料」。

後續步驟