寫入

本頁面列出可傳送至 Bigtable 的寫入要求類型,並說明使用時機和不適用時機。如要瞭解如何在寫入時匯總儲存格中的資料,請參閱「在寫入時匯總值」。

Bigtable Data API 和用戶端程式庫可讓您透過程式輔助方式將資料寫入資料表。Bigtable 會針對每次寫入傳回回應或確認。

每個用戶端程式庫都可以傳送下列類型的寫入要求:

  • 簡易寫入
  • 增量與附加
  • 條件式寫入
  • 批次寫入

Bigtable 用戶端程式庫內建智慧重試功能,可執行簡單和批次寫入作業,也就是說,程式庫可順暢處理暫時無法使用的情況。例如,如果您的應用程式嘗試寫入資料並遇到服務臨時中斷或網路問題,則會自動重試,直到已提交寫入要求或已達到要求期限為止。這項復原能力適用於單一叢集和複製的執行個體,以及單一叢集轉送或多叢集轉送。

如要執行批次和串流寫入作業,可以使用 Bigtable Beam 連接器。詳情請參閱「批次寫入」。

如要瞭解寫入要求的限制,請參閱「配額與限制」。

如需本頁所述寫入要求的 Cloud Bigtable 用戶端程式庫範例,請參閱「寫入範例」。

寫入類型和使用時機

所有寫入要求都包含下列基本元素:

  • 要寫入的資料表名稱。
  • 應用程式設定檔 ID,指示 Bigtable 如何轉送流量。
  • 一或多個異動。異動包含下列元素:
    • 資料欄系列名稱
    • 資料欄限定詞
    • 時間戳記
    • 要寫入資料表的值

異動的時間戳記預設值為當下的日期與時間,以 Unix 紀元 (世界標準時間 1970 年 1 月 1 日 00:00:00) 到當下的時間表示。

根據預設,傳送至 Bigtable 的時間戳記必須是微秒值,精確度最多到毫秒。Bigtable 會拒絕精確度為微秒的時間戳記 (例如 3023483279876543),除非您寫入的資料表時間戳記精細程度為微秒。精細程度為微秒的資料表,可接受使用者提供的時間戳記,精確度可達微秒。這項功能僅適用於 Enterprise Plus 版本的執行個體。

除非您覆寫時間戳記,否則單一寫入要求中的所有異動都會有相同的時間戳記。您可以將寫入要求中所有異動的時間戳記設為相同或不同。

簡易寫入

您可以使用 MutateRow 要求,將單一資料列寫入 Bigtable,其中包含資料表名稱、應使用的應用程式設定檔 ID、資料列索引鍵,以及該資料列最多 100,000 個異動。單一資料列寫入是不可分割的作業。當您對單一資料列進行多次異動時,請使用此類型的寫入作業。

如需示範如何傳送簡單寫入要求的程式碼範例,請參閱「執行簡單寫入」。

不應使用簡易寫入的情況

對下列應用實例來說,簡易寫入並不是寫入資料的最佳方式:

  • 您正在寫入一批具有連續資料列索引鍵的資料。在這種情況下,您應該使用批次寫入,而不是連續的簡單寫入,因為可以在單一後端呼叫中套用連續批次作業。

  • 您需要高總處理量 (每秒資料列數或每秒位元組數),並且不需要低延遲。在這種情況下,批次寫入作業的速度會更快。

增量更新

Bigtable 可讓您建立資料類型為「匯總」的儲存格。如要變更現有資料表儲存格中的值,並在寫入資料時匯總儲存格值,則適合使用匯總儲存格。可用的匯總類型如下:

  • Sum:遞增計數器或保留累計總和。
  • Minimum:將整數傳送至儲存格,Bigtable 會保留兩個值中較小的值。
  • 最大值:將整數傳送至儲存格,Bigtable 會保留兩個值中較高的值。
  • HyperLogLog (HLL):傳送的值會新增至機率集合,其中包含新增至儲存格的所有值。

更新匯總儲存格的要求會與 MutateRow 要求和 AddToCell 或 MergeToCell 異動類型,或其中一種刪除異動類型一起傳送。

附加

如要將資料附加至現有值,可以使用 ReadModifyWriteRow 要求。這項要求包含資料表名稱、應使用的應用程式設定檔 ID、資料列索引鍵,以及寫入資料時要使用的一組規則。每項規則都包含資料欄系列名稱、資料欄限定詞,以及附加值或增量。

系統會依序套用規則。舉例來說,如果您的要求包含附加資料欄值的要求,該資料欄包含值 some 和字串 thing,而相同要求中的後續規則會將相同資料欄附加 body,則該值會在單一原子寫入中修改兩次,產生的值為 somethingbody。後面的規則不會覆寫先前的規則。

您也可以使用 ReadModifyWriteRow 呼叫來遞增整數,但建議您改用匯總儲存格和 AddToCell 或 MergeToCell。只有在值編碼為 64 位元大端序有正負號整數時,才能使用 ReadModifyWrite 遞增值。如果值為空白或不存在,Bigtable 會將其視為零,並進行遞增。

ReadModifyWriteRow 要求是不可分割的。如果因任何原因失敗,系統不會重試。

不適合使用 ReadModifyWriteRow 的情況

請勿在下列情況下傳送 ReadModifyWriteRow 要求:

  • 您可以傳送含有 AddToCell 異動的 MutateRow 要求,處理您的用途。詳情請參閱「在寫入時匯總值」。

  • 您正在使用具有多叢集轉送作業的應用程式設定檔。

  • 您正在使用多個單一叢集應用程式設定檔,且傳送的寫入要求可能與寫入執行個體其他叢集裡同一資料列和資料欄的資料相衝突。使用單一叢集轉送時,寫入要求會傳送至單一叢集,然後複製。

  • 您會使用用戶端程式庫提供的智慧重試功能。無法再次嘗試 ReadModifyWriteRow 要求。

  • 您正在寫入大量資料,且需要快速完成寫入作業。讀取並修改資料列的要求,比單純寫入要求慢。因此,這種寫入方式通常不是大規模作業的最佳做法。

    舉例來說,如果您想計算數百萬個項目 (例如網頁瀏覽次數),應使用 AddToCell 異動 MutateRow,在寫入時更新計數。

條件式寫入

如要檢查資料列是否符合條件,然後根據結果將資料寫入該資料列,請提交 CheckAndMutateRow 要求。這類要求內含資料列索引鍵和資料列篩選器。資料列篩選器是一組規則,用於檢查現有資料的值。只有在符合篩選器檢查的特定條件時,才會將變異提交到資料列的特定資料欄。檢查後寫入的這個程序是以單一不可分割的動作完成。

篩選器要求必須包含下列其中一種或兩種異動類型:

  • 真變異,如果篩選傳回值時套用的變異。
  • 偽變異,如果篩選未產生任何結果時套用的變異。

您在單一寫入要求中最多可以提供 10 萬個變異 (真或偽),且至少必須傳送一個。所有異動完成後,Bigtable 會傳送回應。

由於條件式寫入會讀取資料列來評估篩選器,因此呼叫端必須具備資料表的 bigtable.tables.readRows 和 bigtable.tables.mutateRows 權限 (或已授權檢視表的對等 bigtable.authorizedViews.readRows 和 bigtable.authorizedViews.mutateRows 權限)。詳情請參閱「存取控管」。

如需示範如何傳送條件式寫入的程式碼範例,請參閱「條件式寫入值」。

不應使用條件式寫入的情況

您不能對下列應用實例使用條件式寫入:

  • 您使用的應用程式設定檔具有多叢集轉送功能。

  • 您正在使用多個單一叢集應用程式設定檔,且傳送的寫入要求可能與寫入執行個體其他叢集裡同一資料列和資料欄的資料相衝突。單一叢集轉送作業會將寫入要求傳送到單一叢集,然後予以複製。

  • 您正在寫入大量資料,需要快速完成寫入作業。與 ReadModifyWriteRow 類似,條件式寫入要求必須先讀取資料列,才能修改資料列,因此 CheckAndModifyRow 要求的速度比簡單寫入要求慢。因此,這種寫入方式通常不適合大規模使用。

批次寫入

您可以使用 MutateRows 要求,透過單一呼叫寫入多個資料列。MutateRows 要求包含一組最多 100,000 個項目,每個項目都會以不可分割的方式套用。每個項目由一個資料列索引鍵和至少一個套用於資料列的變異組成。一項批次寫入要求的所有項目最多可包含 10 萬個變異。舉例來說,批次寫入可能包含下列任一排列組合:

  • 10 萬個項目,每個項目有 1 個變異。
  • 1 個項目,其中有 10 萬個變異。
  • 1,000 個項目,每個項目有 100 個變異

MutateRows 要求中的每個項目都是不可分割的,但要求本身並非如此。如有需要,Bigtable 會重試批次中失敗的項目,直到所有寫入作業都成功,或達到要求期限為止。接著,系統會傳回回應,指出批次中的每項寫入作業,以及寫入作業是否成功。

如需示範如何傳送批次寫入作業的程式碼範例,請參閱「執行批次寫入作業」。

不應使用批次寫入的情況

  • 您要將大量資料寫入不相鄰的資料列。Bigtable 會依資料列索引鍵的字母順序儲存資料,也就是字母順序的二進位等效值。因此,如果要求中的資料列索引鍵不相似,Bigtable 會依序處理,而非平行處理。總處理量會很高,但延遲時間也會很長。如要避免高延遲,請在資料列索引鍵相似,且 Bigtable 會寫入相近的資料列時,使用 MutateRows。如果資料列彼此不相近,請使用 MutateRow 或簡單寫入。

  • 您要求對相同資料列執行多個變異。在這種情況下,如果透過單一簡易寫入要求執行所有異動,成效會更好。這是因為在簡單寫入中,所有變更都會在單一原子動作中提交,但批次寫入會強制將變更序列化至同一資料列,導致延遲。

批次寫入流量控制

如果您使用下列任一方式傳送批次寫入 (包括刪除),可以在程式碼中啟用批次寫入流量控制。

為 Dataflow 工作啟用批次寫入流量控管功能後,Bigtable 會自動執行下列操作:

  • 限制流量,避免 Bigtable 叢集超載
  • 確保叢集負載足以觸發 Bigtable 自動調度資源功能 (如已啟用),以便在需要時自動將更多節點新增至叢集

這些動作可防止叢集超載和工作失敗,您不必在執行批次寫入前手動調度叢集資源。啟用流量控管功能後,叢集會在 Dataflow 工作期間調度資源,而非在工作開始前,因此工作可能需要較長時間才能完成,比手動調度叢集資源更耗時。

您必須使用設定為單一叢集轉送的應用程式設定檔。您不一定要為目的地叢集啟用 Bigtable 自動調度資源功能,但啟用後,就能充分運用批次寫入流量控管功能。您可以像使用其他工作一樣,使用 Dataflow 自動調度資源功能。

如要進一步瞭解 Bigtable 自動調度資源功能,請參閱「自動調度資源」。如要瞭解應用程式設定檔轉送政策,請參閱「應用程式設定檔總覽」。

如需程式碼範例,請參閱「啟用批次寫入流量控管」。

將資料寫入授權檢視表

如要將資料寫入授權檢視表,您必須使用下列其中一項:

  • gcloud CLI
  • Java 適用的 Bigtable 用戶端

其他 Bigtable 用戶端程式庫尚不支援授權檢視權限。

將資料寫入授權檢視表時,除了資料表 ID 外,您還須提供授權檢視表 ID。

對授權檢視表的所有寫入作業,都會直接套用至基礎資料表。

授權檢視表定義限制

在授權檢視表中,可寫入資料的資料列或資料欄會受到授權檢視表定義的限制。換句話說,您只能寫入符合授權檢視表指定條件的資料列和資料欄。

舉例來說,如果授權檢視表是由資料列索引鍵前置字串 examplepetstore1 定義,則您無法使用資料列索引鍵 examplepetstore2 寫入資料;資料列索引鍵值的開頭必須包含整個字串 examplepetstore1。

同樣地,如果授權檢視表是由資料欄限定詞前置字串 order-phone 定義,您可以使用資料欄限定詞 order-phone123 寫入資料,但無法使用資料欄限定詞 order-tablet。

寫入要求也無法參照授權檢視表以外的資料,例如在條件式寫入要求中檢查值。

如果要求寫入或參照授權檢視表以外的資料,系統會傳回 PERMISSION_DENIED 錯誤訊息。

複製

當複製執行個體的某個叢集收到寫入作業時,該作業會立即複製到執行個體中的其他叢集。

完整性

您傳送至複製執行個體的每個 MutateRows 要求,都會在要求轉送至的叢集上,以單一不可分割動作的形式提交。當寫入作業複製到執行個體中的其他叢集時,這些叢集也會將寫入作業視為不可分割的作業。叢集不會接收部分異動;異動會成功或失敗,並以不可分割的方式套用至所有修改的儲存格。

一致性

寫入的資料需要多久時間才能讀取,取決於多項因素,包括執行個體中的叢集數量,以及應用程式設定檔使用的轉送類型。

如果是單一叢集執行個體,系統可以立即讀取資料,但如果執行個體有多個叢集 (也就是使用複製功能),Bigtable 則會最終一致。只要將要求轉送至同一個叢集,即可達到讀寫一致性。

您可以建立及使用一致性權杖,並在傳送寫入要求後,以 StandardReadRemoteWrites 模式呼叫 CheckConsistency。權杖會檢查複製一致性。一般來說,您會在傳送一批寫入作業後,或在特定時間間隔 (例如一小時) 後建立一致性權杖。接著,您可以將權杖交給其他程序使用,例如發出讀取要求的模組,該模組會使用權杖確認所有資料都已複製,然後才嘗試讀取。

如果您在建立憑證後要使用憑證,則在第一次使用時可能需要幾分鐘時間來檢查是否一致。此延遲是因為每個叢集都會檢查其他叢集,以確保不會再有資料傳來。初次使用後,或第一次使用憑證等候幾分鐘後,憑證會在每次使用時立即生效。

衝突解決

Bigtable 資料表中的每個儲存格值,都是由四元組 (資料列索引鍵、資料欄系列、資料欄限定詞、時間戳記) 唯一識別。如要進一步瞭解這些 ID,請參閱「Bigtable 儲存空間模型」。如果兩個具有完全相同四元組的寫入作業傳送至兩個不同的叢集,Bigtable 會根據伺服器端時間,使用內部最後寫入優先演算法自動解決衝突。Bigtable 的「以最後寫入者為準」實作方式是確定性的,當複製作業趕上進度時,所有叢集的四元組值都會相同。

後續步驟