將資料匯出至 Bigtable (反向 ETL)
本文件說明如何設定從 BigQuery 到 Bigtable 的逆向 ETL (RETL)。您可以使用 EXPORT
DATA
陳述式,將資料從 BigQuery 資料表匯出至 Bigtable 資料表。
您可以使用 RETL 工作流程將 Bigtable 的低延遲和高處理量與 BigQuery 的分析功能結合。這個工作流程可讓您為應用程式使用者提供資料,且不會耗盡 BigQuery 的配額和限制。
Bigtable 資料表的特性
Bigtable 資料表與 BigQuery 資料表有幾項不同之處:
- Bigtable 和 BigQuery 資料表都是由資料列組成,但 Bigtable 資料列是由資料列鍵和資料欄系列組成,而資料欄系列可包含任意數量的資料欄,且所有資料欄都屬於同一個資料欄系列。
- 特定資料表的資料欄系列會在建立資料表時建立,但也可以在之後新增或移除。建立資料欄系列時,無須指定屬於該系列的資料欄。
- Bigtable 資料欄不需要事先定義,而且可用於在資料表內的資料大小限制內,以名稱 (也稱為限定詞) 儲存資料。
- Bigtable 資料欄可以包含資料表內的資料大小限制範圍內的任何二進位值。
- Bigtable 資料欄一律會有時間維度 (也稱為「版本」)。只要時間戳記不相同,同一個欄的任何資料列都可以儲存任意數量的值。
- Bigtable 時間戳記是以 Unix 紀元時間為基準,以微秒為單位計算,例如 0 代表 1970-01-01T00:00:00 UTC。時間戳記必須是微秒的非負數,精確度為毫秒 (僅接受 1000us 的倍數)。Bigtable 的預設時間戳記為 0。
- Bigtable 中的資料可依資料列索引鍵、多個資料列索引鍵、資料列索引鍵範圍或篩選器讀取。除了完整資料表掃描作業,所有類型的讀取要求都需要至少一個資料列鍵或資料列鍵範圍。
如要瞭解如何準備 BigQuery 結果,以便匯出至 Bigtable,請參閱「準備匯出用查詢結果」。
事前準備
您必須建立 Bigtable 執行個體和 Bigtable 資料表,才能接收匯出的資料。
授予身分與存取權管理 (IAM) 角色,讓使用者取得執行本文件中各項工作的必要權限。
必要的角色
如要取得匯出 BigQuery 資料至 Bigtable 所需的權限,請要求管理員在專案中授予您下列 IAM 角色:
-
從 BigQuery 資料表匯出資料:
BigQuery 資料檢視器 (
roles/bigquery.dataViewer
) -
執行匯出工作:
BigQuery 使用者 (
roles/bigquery.user
) -
將資料寫入 Bigtable 資料表:
Bigtable 使用者 (
roles/bigtable.user
)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
限制
- 編碼只能使用
BINARY
和TEXT
。 - 目的地 Bigtable 應用程式設定檔必須設定為使用單叢集轉送和低要求優先順序。
- 您必須設定 Bigtable 應用程式設定檔,將資料轉送至與 BigQuery 資料集同處的 Bigtable 叢集。詳情請參閱位置注意事項。
- BigQuery Enterprise 或 Enterprise Plus 版本支援匯出至 Bigtable。不支援 BigQuery 標準版和隨選運算。
- 只有含有
QUERY
指派的預留項目,才能匯出至 Bigtable。
位置注意事項
- 如果 BigQuery 資料集位於多個地區,則必須設定 Bigtable 應用程式設定檔,將資料路由至該多地區內的 Bigtable 叢集。舉例來說,如果您的 BigQuery 資料集位於
US
多區域,Bigtable 叢集可以位於美國境內的us-west1
(俄勒岡) 區域。 - 如果 BigQuery 資料集位於單一地區,則必須設定 Bigtable 應用程式設定檔,將資料路由至位於相同地區的 Bigtable 叢集。舉例來說,如果您的 BigQuery 資料集位於
asia-northeast1
(東京) 地區,Bigtable 叢集也必須位於asia-northeast1
(東京) 地區。
詳情請參閱「Bigtable 位置」。
支援的 BigQuery 類型
系統支援下列資料類型,並可將這些資料寫入 Bigtable:
BigQuery 類型 | 寫入的 Bigtable 值 |
---|---|
BYTES |
匯出內容不經過任何修改。 |
STRING |
已轉換為 BYTES 。 |
INTEGER |
如果 bigtable_options.column_families.encoding 設為 BINARY ,則會以 8 位元組大端序格式 (先寫入最高位元組) 寫入值。如果 bigtable_options.column_families.encoding 設為 TEXT ,則值會以可供人類閱讀的字串形式寫入,代表數字。 |
FLOAT |
以 IEEE 754 8 位元組輸出格式寫入值。 |
BOOLEAN |
如果 bigtable_options.column_families.encoding 設為 BINARY ,則值會以 1 個位元組的值寫入 (false = 0x00 或 true = 0x01)。如果 bigtable_options.column_families.encoding 設為 TEXT ,則會以文字 ("true" 或 "false" ) 的形式寫入值。 |
JSON |
系統會將
JSON 類型的匯出資料欄視為屬於特定 Bigtable 資料欄系列的一組資料欄。JSON 物件的成員會解讀為資料欄,其值會寫入 Bigtable。您可以使用 bigtable_options 設定調整要寫入的資料欄名稱。 例如:
JSON '{"FIELD1": "VALUE1", "FIELD2": "VALUE2"}' as MY_COLUMN_FAMILY 其中 VALUE1 和 VALUE2 值會寫入 Bigtable,並分別設為資料欄 FIELD1 和 FIELD2,並設為資料欄系列 MY_COLUMN_FAMILY。
|
STRUCT |
系統會將
STRUCT 類型的匯出資料欄視為屬於特定 Bigtable 資料欄系列的一組資料欄。系統會將結構體成員視為資料欄,並將其值寫入 Bigtable。您可以使用 bigtable_options 設定調整要寫入的資料欄名稱。 例如:
STRUCT<FIELD1 STRING, FIELD2 INTEGER> as MY_COLUMN_FAMILY 其中 FIELD1 和 FIELD2 值會寫入 Bigtable,並以資料欄 FIELD1 和 FIELD2 的形式存入資料欄系列 MY_COLUMN_FAMILY。
|
這些支援的資料類型與 BigQuery 的外部 Bigtable 資料表類似。
Bigtable 中的 NULL
值
Bigtable 中的 NULL
值有以下限制:
Bigtable 沒有
NULL
值的類比。在 Bigtable 中,針對特定資料欄系列和資料欄匯出NULL
值會刪除 Bigtable 列中的現有值。如果在匯出前,沒有指定列鍵、資料欄系列、資料欄限定詞和時間戳記的 Bigtable 值,匯出的
NULL
值就不會對 Bigtable 列產生影響。匯出
STRUCT
或JSON
類型的NULL
值時,系統會刪除受影響資料列中屬於對應資料欄系列的所有資料欄值。您應將NULL
值轉換為STRUCT
或JSON
類型,以便 SQL 引擎為其附加正確的類型。以下查詢會使用一組指定的資料列鍵,從資料欄系列column_family1
刪除所有資料:EXPORT DATA OPTIONS (...) AS SELECT rowkey, CAST(NULL as STRUCT<INT64>) AS column_family1 FROM T
匯出時會略過含有
NULL
列鍵的資料列。系統會在匯出統計資料中傳回略過的資料列數給呼叫端。
使用 bigtable_options
設定匯出作業
您可以在匯出期間使用 bigtable_options
設定,以彌補 BigQuery 和 Bigtable 儲存空間模型之間的差異。設定會以 JSON 字串的形式表示,如以下範例所示:
EXPORT DATA OPTIONS( uri="https://bigtable.googleapis.com/projects/PROJECT_ID
/instances/INSTANCE_ID
/appProfiles/APP_PROFILE_ID
/tables/TABLE
", bigtable_options = """{ "columnFamilies": [{ "familyId": "COLUMN_FAMILY_NAME
", "encoding": "ENCODING_VALUE
", "columns": [ { "qualifierString": "BIGTABLE_COLUMN_QUALIFIER
", ["qualifierEncoded": "BASE_64_ENCODED_VALUE
",] "fieldName": "BIGQUERY_RESULT_FIELD_NAME
" } ] }] }""" )
下表說明 bigtable_options
設定中可能使用的欄位:
欄位名稱 | 說明 |
---|---|
columnFamilies |
資料欄系列描述符的陣列。 |
columnFamilies.familyId |
Bigtable 資料欄系列的 ID。 |
columnFamilies.encoding |
值可設為 BINARY 或 TEXT 。如要瞭解如何編碼類型,請參閱「支援的 BigQuery 類型」。 |
columnFamilies.columns |
Bigtable 資料欄對應項目的陣列。 |
columnFamilies.columns.qualifierString |
選用:Bigtable 資料欄限定詞。如果欄限定詞沒有非 UTF-8 代碼,請指定這個值。qualifierString 和 qualifierEncoding 欄位互斥,如果未指定 qualifierString 或 qualifierEncoded ,系統會使用 fieldName 做為資料欄限定詞。 |
columnFamilies.columns.qualifierEncoded |
選用:Base64 編碼的資料欄限定詞。與 qualifierString 類似,如果資料欄限定條件必須包含非 UTF-8 編碼,則可使用此函式。 |
columnFamilies.columns.fieldName |
必填:BigQuery 結果集欄位名稱。在某些情況下,可以是空字串。如需空白 fieldName 值如何與簡單類型欄位搭配使用的範例,請參閱「準備匯出的查詢結果」。 |
準備要匯出的查詢結果
如要將查詢結果匯出至 Bigtable,結果必須符合下列條件:
- 結果集必須包含
rowkey
資料欄,其類型為STRING
或BYTES
。 - 資料列鍵、資料欄限定詞、值和時間戳記不得超過 Bigtable 資料表內的資料大小限制。
- 結果集中至少須包含
rowkey
以外的一個資料欄。 - 每個結果集資料欄都必須是 支援的 BigQuery 類型之一。匯出至 Bigtable 前,必須先將所有不支援的欄位類型轉換為其中一個支援的類型。
Bigtable 不要求資料欄限定詞必須是有效的 BigQuery 資料欄名稱,而且支援使用任何位元組。如要瞭解如何覆寫匯出作業的目標欄限定詞,請參閱「使用 bigtable_options
設定匯出作業」。
如果您使用匯出的值搭配 Bigtable API (例如 ReadModifyWriteRow
),則所有數值都必須使用正確的二進位編碼。
根據預設,如果是 STRUCT
或 JSON
以外的類型,則獨立結果資料欄會解讀為值,且目標資料欄系列等於結果資料欄名稱,資料欄限定詞等於空白字串。
為說明如何編寫這些資料類型,請參考下列 SQL 範例,其中 column
和 column2
是獨立的結果欄:
SELECT
x as column1, y as column2
FROM table
在這個範例查詢中,SELECT x as column1
會在處理 JSON
或 STRUCT
以外的類型時,將值寫入 column1
資料欄系列和 ''
(空字串) 資料欄限定詞下的 Bigtable。
您可以使用 bigtable_options
設定,變更這些類型在匯出內容中寫入的方式,如以下範例所示:
EXPORT DATA OPTIONS ( … bigtable_options="""{ "columnFamilies" : [ { "familyId": "ordered_at", "columns": [ {"qualifierString": "order_time", "fieldName": ""} ] } ] }""" ) AS SELECT order_id as rowkey, STRUCT(product, amount) AS sales_info, EXTRACT (MILLISECOND FROM order_timestamp AT TIME ZONE "UTC") AS ordered_at FROM T
在這個範例中,BigQuery 資料表 T
包含以下資料列:
order_id |
order_timestamp |
product |
amount |
---|---|---|---|
101 | 2023-03-28T10:40:54Z | 搖桿 | 2 |
如果您將上述 bigtable_options
設定與資料表 T
搭配使用,Bigtable 會寫入下列資料:
rowkey |
sales_info (資料欄系列) |
ordered_at (資料欄系列) |
|||
---|---|---|---|---|---|
101 | 產品 | amount | order_time | ||
1970-01-01T00:00:00Z | 搖桿 | 1970-01-01T00:00:00Z | 2 | 1680000054000 |
1680000054000
代表 2023-03-28T10:40:54Z
,以世界標準時間時區的 Unix Epoch 紀元時間為起點,以毫秒為單位。
使用 _CHANGE_TIMESTAMP
為資料列中所有儲存格設定時間戳記
您可以將 TIMESTAMP
類型的 _CHANGE_TIMESTAMP
欄新增至匯出結果。寫入 Bigtable 的每個儲存格都會使用匯出結果列的 _CHANGE_TIMESTAMP
中所列的時間戳記值。
Bigtable 不支援早於 Unix 紀元 (1970-01-01T00:00:00Z) 的時間戳記。如果 _CHANGE_TIMESTAMP
值為 NULL
,系統會使用 0
的 Unix Epoch 紀元時間做為預設時間戳記值。
以下查詢會使用資料表 T
的 order_timestamp
欄中指定的時間戳記,為 product
和 amount
欄寫入儲存格。
EXPORT DATA OPTIONS (...) AS SELECT rowkey, STRUCT(product, amount) AS sales_info, order_timestamp as _CHANGE_TIMESTAMP FROM T
持續匯出
如果您想持續處理匯出查詢,可以將其設為持續查詢。
匯出多個具有相同 rowkey
值的結果
當您匯出包含多個具有相同 rowkey
值的資料列結果時,寫入 Bigtable 的值會最終出現在同一個 Bigtable 資料列中。
您可以使用這個方法,在同一個資料列中產生多個版本的資料欄值。在這個範例中,BigQuery 中的 orders
資料表包含以下資料:
id |
customer |
order_timestamp |
amount_spent |
---|---|---|---|
100 | Bob | 2023-01-01T10:10:54Z | 10.99 |
101 | Alice | 2023-01-02T12:10:50Z | 102.7 |
102 | Bob | 2023-01-04T15:17:01Z | 11.1 |
接著,使用者執行下列 EXPORT DATA
陳述式:
EXPORT DATA OPTIONS (
uri="https://bigtable.googleapis.com/projects/PROJECT-ID/instances/INSTANCE-ID/appProfiles/APP_PROFILE_ID
/tables/TABLE",
format="CLOUD_BIGTABLE"
) AS
SELECT customer as rowkey, STRUCT(amount_spent) as orders_column_family, order_timestamp as _CHANGE_TIMESTAMP
FROM orders
將這項陳述式與 BigQuery orders
資料表搭配使用,會導致下列資料寫入 Bigtable:
orders_column_family | ||
---|---|---|
資料列索引鍵 | amount_spent | |
Alice | 2023-01-02T12:10:50Z | 102.7 |
Bob | 2023-01-01T10:10:54Z | 10.99 |
2023-01-04T15:17:01Z | 11.1 |
匯出至 Bigtable 時,系統會將新值合併至資料表,而不是取代整個資料列。如果 Bigtable 中已有資料列鍵的值,則新值可部分或完全覆寫先前的值,這取決於所寫入儲存格的資料欄家族、資料欄名稱和時間戳記。
將多個資料欄匯出為 Protocol Buffer (Protobuf) 值
通訊協定緩衝區提供靈活且有效率的機制,可用於將結構化資料序列化。考量 BigQuery 和 Bigtable 之間處理不同類型的方式,匯出為 Protobuf 可能會很有幫助。您可以使用 BigQuery 使用者定義函式 (UDF),將資料匯出為 Protobuf 二進位值,並傳送至 Bigtable。詳情請參閱「將資料匯出為 Protobuf 欄」。
匯出最佳化
您可以修改 Bigtable 目的地叢集中的節點數,變更從 BigQuery 匯出至 Bigtable 的記錄吞吐量。處理量 (每秒寫入的列數) 會隨著目的地叢集中的節點數量線性調整。舉例來說,如果您將目的地叢集中的節點數量加倍,匯出傳輸量也會大致加倍。
定價
匯出標準查詢中的資料時,系統會根據資料提取定價收費。匯出持續查詢中的資料時,系統會根據 BigQuery 運算能力價格收費。如要執行持續查詢,您必須具備使用 Enterprise 或 Enterprise Plus 版本的預留,以及使用 CONTINUOUS
工作類型的預留指派。
匯出資料後,系統會因您在 Bigtable 中儲存資料而向您收取費用。詳情請參閱「Bigtable 定價」。