寫入

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

您可以使用 Bigtable Data API 和用戶端程式庫,以程式輔助方式將資料寫入資料表。Bigtable 會針對每次寫入作業傳回回應或確認訊息。

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

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

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

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

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

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

寫入類型和使用時機

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

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

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

傳送至 Bigtable 的時間戳記必須是微秒值,精確的位數只到毫秒。舉例來說,3023483279876543 這個微秒值會遭到拒絕。在本範例中,可接受的時間戳記值為 3023483279876000。

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

簡易寫入

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

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

不應使用簡易寫入的情況

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

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

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

增量更新

Bigtable 可讓您建立資料類型為「匯總」的儲存格。如果您想變更現有表格儲存格中的值,並在寫入資料時匯總儲存格值,則匯總儲存格是最佳選擇。可用的匯總類型如下:

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

如要更新匯總儲存格,請傳送 MutateRow 要求,並將變動類型設為 AddToCell、MergeToCell 或其中一種刪除變動類型。

附加

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

系統會依序套用規則。舉例來說,如果要求包含將字串 thing 附加至含有值 some 的資料欄,且同一要求中的後續規則會將 body 附加至同一資料欄,則值會在單一不可分割的寫入作業中修改兩次,最終值為 somethingbody。後面的規則不會覆寫先前的規則。

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

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

不適用的情況 ReadModifyWriteRow

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

  • 如要處理您的用途,請傳送含有 AddToCell 變動的 MutateRow 要求。詳情請參閱「在寫入時彙整值」。

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

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

  • 您依賴用戶端程式庫提供的智慧重試功能。ReadModifyWriteRow 要求無法重試。

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

    舉例來說,如要計算網頁瀏覽次數等數百萬的項目,您應使用 MutateRow 搭配 AddToCell 突變,在寫入時更新計數。

條件式寫入

如要檢查資料列是否符合條件,然後根據結果將資料寫入該資料列,請提交 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 自動調度資源功能,請參閱「自動調度資源」。如要瞭解應用程式設定檔轉送政策,請參閱應用程式設定檔簡介。

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

將資料寫入授權 view

如要將資料寫入授權檢視區,請使用下列任一項目:

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

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

將資料寫入授權 view 時,除了資料表 ID,您還需要提供授權 view ID。

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

授權 view 定義限制

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

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

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

寫入要求也不得參照授權檢視區塊以外的資料,例如在條件式寫入要求中檢查值時。

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

複製

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

完整性

您傳送至複製執行個體的每項 MutateRows 要求,都會在要求路由傳送至的叢集上,以單一不可分割的動作提交。當寫入作業複製到執行個體中的其他叢集時,這些叢集也會各自以不可分割的作業接收寫入作業。叢集不會收到部分突變;突變會針對修改的所有儲存格,以原子方式成功或失敗。

一致性

寫入資料可供讀取的時間取決於多項因素,包括執行個體中的叢集數量,以及應用程式設定檔使用的路由類型。

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

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

如果您在建立權杖後立即使用,第一次使用時,系統可能需要幾分鐘的時間檢查一致性。此延遲是因為每個叢集都會檢查其他叢集,以確保不會再有資料傳來。首次使用後,或等待幾分鐘再首次使用權杖,權杖每次都會立即成功使用。

解決衝突

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

後續步驟