讀取

本頁面說明您可以傳送至 Bigtable 的讀取要求類型、討論效能影響,並針對特定類型的查詢提出幾項建議。閱讀本頁之前,請先熟悉 Bigtable 總覽

總覽

Bigtable 的讀取要求會以鍵值順序串流傳回所要求資料列的內容,也就是按照儲存順序傳回。您可以讀取任何已傳回回應的寫入作業。

資料表支援的查詢應有助於判斷最適合您用途的讀取類型。Bigtable 讀取要求大致可分為兩類:

  • 讀取單一資料列
  • 掃描或讀取多個資料列

讀取作業在資料列層級為不可部分完成。也就是說,當您傳送資料列的讀取要求時,Bigtable 會傳回整個資料列,或在要求失敗時不傳回任何資料列。除非您明確要求,否則系統絕不會傳回部分資料列。

強烈建議您使用 Cloud Bigtable 用戶端程式庫從資料表讀取資料,而不是直接呼叫 API。程式碼範例提供多種語言版本,可讓您瞭解如何傳送讀取要求。所有讀取要求都會發出 ReadRows API 呼叫。

使用 Data Boost 無伺服器運算讀取資料

Bigtable Data Boost 可讓您執行批次讀取工作和查詢,不會影響每日應用程式流量。Data Boost 是一項無伺服器運算服務,可讓您讀取 Bigtable 資料,同時讓核心應用程式使用叢集的節點進行運算。

Data Boost 非常適合用於掃描,但不建議用於單列讀取。Data Boost 無法用於反向掃描。如要瞭解詳情和資格條件,請參閱 Data Boost 總覽

單一資料列讀取

您可以根據列鍵要求單一列。單列讀取 (又稱點讀取) 與 Data Boost 不相容。以下列變體提供程式碼範例:

掃描檔

掃描是讀取 Bigtable 資料最常見的方式。您可以指定資料列鍵前置字元,或指定開始和結束資料列鍵,從 Bigtable 讀取連續資料列範圍或多個資料列範圍。我們提供下列變體的程式碼範例:

反向掃描

反向掃描可讓您指定資料列鍵前置字串或資料列範圍,以反向讀取資料列範圍。資料列索引鍵前置字元會做為掃描的起始點,以便向後讀取。如果您指定資料列範圍,系統會使用結尾資料列鍵做為掃描的起始點。

反向掃描適用於下列情境:

反向掃描的效率不如正向掃描。一般來說,請設計資料列鍵,讓大多數掃描作業都是向前掃描。如要進行短掃描 (例如 50 列以下),請使用反向掃描,以維持低延遲的回應時間。

如要反向掃描,請將 ReadRowsRequest 欄位 reversed 的值設為 true。預設值為 false。

使用下列用戶端程式庫時,可以進行反向掃描:

  • 適用於 C++ 的 Bigtable 用戶端程式庫 2.18.0 以上版本
  • Go 專用的 Bigtable 用戶端程式庫 1.21.0 以上版本
  • Java 適用的 Bigtable 用戶端程式庫 2.24.1 以上版本
  • 適用於 Java 的 Bigtable HBase 用戶端 2.10.0 以上版本

如需示範如何使用反向掃描的程式碼範例,請參閱「反向掃描」。

應用實例範例

以下範例說明如何使用反向掃描,找出顧客上次變更密碼的時間,以及特定日期前後的產品價格波動。

重設密碼

假設您的資料列鍵各包含一個客戶 ID 和一個日期,格式為 123ABC#2022-05-02,其中一個資料欄是 password_reset,儲存密碼重設時間。Bigtable 會自動依字典順序儲存資料,如下所示。請注意,如果密碼未重設,資料列 (天數) 就不會顯示這個資料欄。

`123ABC#2022-02-12,password_reset:03`
`123ABC#2022-04-02,password_reset:11`
`123ABC#2022-04-14`
`123ABC#2022-05-02`
`223ABC#2022-05-22`

如要找出顧客上次123ABC重設密碼的時間,可以從 123ABC#123ABC#<DATE> 倒向掃描一段時間範圍,使用今天的日期或未來的日期,找出所有包含 password_reset 資料欄的資料列,並將資料列上限設為 1。

價格異動

在本範例中,資料列鍵包含產品、型號和時間戳記的值,其中一個資料欄則包含特定時間的產品和型號價格。

`productA#model2#1675604471,price:82.63`
`productA#model2#1676219411,price:82.97`
`productA#model2#1677681011,price:83.15`
`productA#model2#1680786011,price:83.99`
`productA#model2#1682452238,price:83.12`

假設您想找出 2023 年 2 月 14 日前後的價格波動,即使資料表中沒有該特定日期的資料列鍵,您也可以從資料列鍵 productA#model2#1676376000 開始,向前掃描 N 個資料列,然後從同一個起始資料列向後掃描相同數量的資料列。這兩次掃描會提供指定時間前後的價格。

經過篩選的讀取

如果您只需要包含特定值或部分資料列的資料列,可以在讀取要求中使用篩選器。篩選器可讓您高度選擇要使用的資料。

您也可以使用篩選器,確保讀取作業符合表格使用的垃圾收集政策。如果您經常在現有資料欄中寫入新的時間戳記儲存格,這個做法就特別實用。由於垃圾收集最多可能需要一週的時間才能移除過期資料,因此使用時間戳記範圍篩選器讀取資料,可確保您不會讀取超過需求的資料。

篩選器總覽會詳細說明可使用的篩選器類型。使用篩選器一文提供多種語言的範例。

從授權檢視表讀取資料

如要從授權檢視區塊讀取資料,請使用下列其中一種方式:

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

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

系統支援呼叫 Bigtable Data API 的 ReadRowsSampleRowKeys 方法。建立用戶端時,除了提供表格 ID,您也需要提供已授權檢視表 ID。

從持續性具體化檢視表讀取資料

您可以使用 SQL 或 ReadRows Data API 呼叫,從持續具體化檢視區塊讀取資料。持續性具體化檢視表為唯讀。具體化檢視中的資料會根據定義該檢視的查詢輸入。

SQL

如要使用 SQL 從持續具體化檢視區塊讀取資料,可以使用 Bigtable Studio 查詢編輯器,或支援 SQL 查詢的用戶端程式庫

SQL 會自動將查詢結果顯示為已輸入的資料欄,因此您不必在查詢中處理編碼。

建立連續具體化檢視區塊時,Bigtable 會自動為資料表建立資料列鍵結構定義,定義檢視區塊的結構化資料列鍵。如要進一步瞭解如何使用 SQL 查詢結構化資料列鍵,請參閱結構化資料列鍵查詢

Data API

如果您打算透過 Bigtable 其中一個用戶端程式庫的 ReadRows 呼叫,從持續性具體化檢視區塊讀取資料,請檢查用於定義檢視區塊的 SQL 查詢。請注意,檢視區塊是否已定義 _key 資料欄 (建議用於要透過 ReadRows 讀取的檢視區塊),以及是否含有 _timestamp 資料欄。

您也必須瞭解每個資料欄的類型,並在應用程式程式碼中解碼資料欄資料。

系統會根據檢視定義中資料欄的輸出類型,使用下表所述的編碼方式,儲存連續具體化檢視中的匯總值。

類型 編碼
BOOL 1 位元組值,1 = true,0 = false
BYTES 無編碼
INT64 (或 INT、SMALLINT、INTEGER、BIGINT、TINYINT、BYTEINT) 64 位元大端
FLOAT64 64 位元 IEEE 754,不含 NaN 和 +/-inf
STRING UTF-8
TIME/TIMESTAMP 64 位元整數,代表自 Unix 紀元起算的微秒數 (與 GoogleSQL 一致)
詳情請參閱 Data API 參考資料中的「 編碼」。

除了檢視中每個資料欄的類型,您還需要知道資料欄系列和資料欄限定詞。預設資料欄系列稱為 default,而資料欄限定詞是定義查詢中指定的別名。舉例來說,請考量以這個查詢定義的持續性 materialized view:

SELECT
  _key,
  SUM(clicks) AS sum_clicks
FROM
  mytable
GROUP BY
  sum_clicks

使用 ReadRows 查詢檢視區塊時,您會提供資料欄系列 default 和資料欄限定符 sum_clicks

讀取和效能

使用篩選器的讀取作業比不使用篩選器的讀取作業慢,且會增加 CPU 使用率。另一方面,這些函式會限制傳回的資料量,因此可大幅減少網路頻寬用量。一般而言,篩選器應是用來控管輸送量效率,而非延遲。

如要提升讀取效能,請考慮下列策略:

  1. 盡可能限制資料列集。限制節點必須掃描的資料列數,是改善首封位元組時間和整體查詢延遲的第一步。如果不限制資料列集,Bigtable 幾乎肯定必須掃描整個資料表。因此,建議您設計結構定義時,讓最常見的查詢能以這種方式運作。

  2. 限制資料列集後,如要進一步調整效能,請嘗試新增基本篩選器。限制傳回的資料欄集或版本數量通常不會增加延遲時間,有時還能協助 Bigtable 更有效率地略過每個資料列中不相關的資料。

  3. 如果想在採用前兩種策略後進一步微調讀取效能,請考慮使用較複雜的篩選器。您可能基於以下原因嘗試這麼做:

    • 但還是會收到許多不想要的資料。
    • 您希望將查詢下推至 Bigtable,藉此簡化應用程式程式碼。

    但請注意,如果篩選器允許大部分掃描資料通過,則需要條件、交錯或規則運算式比對大型值的篩選器,往往弊多於利。這種危害會導致叢集中的 CPU 使用率提高,但用戶端卻無法大幅節省資源。

除了這些策略,請避免在單一讀取要求中讀取大量不連續的資料列鍵或資料列範圍。當您在單一要求中要求數百個資料列索引鍵或資料列範圍時,Bigtable 會掃描表格並依序讀取所要求的資料列。缺乏平行處理能力會影響整體延遲時間,且任何命中熱節點的讀取作業都可能增加尾端延遲時間。要求的列範圍越多,讀取作業完成所需的時間就越長。如果無法接受這種延遲,您應該改為傳送多個並行要求,每個要求擷取的資料列範圍較小。

一般來說,在單一要求中讀取更多資料列範圍可提升總處理量,但不會縮短延遲時間。在多個並行要求中讀取較少的資料列範圍,可縮短延遲時間,但無法提升總處理量。在延遲和輸送量之間取得適當平衡,取決於應用程式的需求,您可以調整並行讀取要求計數,以及單一要求中的資料列範圍數量,以達到適當平衡。

大型資料列

Bigtable 會強制執行下列大型資料列限制:

  • 資料列大小上限為 256 MB。如需讀取超過限制的資料列,可以將要求分頁,並使用 cells per row limit 篩選器cells per row offset 篩選器。請注意,如果寫入作業在分頁讀取要求之間抵達資料列,讀取作業可能不是不可分割。

  • ReadRows API 呼叫的大小上限為 512 KB。如果超出限制,Bigtable 會傳回 INVALID_ARGUMENT 錯誤。

後續步驟