読み取り
このページでは、Bigtable に送信できる読み取りリクエストの種類と、パフォーマンスへの影響について説明し、特定の種類のクエリに関する推奨事項を示します。このページを読む前に、Bigtable の概要を理解する必要があります。
概要
Bigtable への読み取りリクエストは、リクエストされた行の内容をキー順にストリーミング バックします。つまり、行の内容は保存されている順序で返されます。レスポンスを返した書き込みを読み取ることができます。
テーブルがサポートするクエリは、ユースケースに最適な読み取りのタイプを決定する際に有用です。Bigtable の読み取りリクエストは、次の 2 つの一般カテゴリに分類されます。
- 単一行の読み取り
- スキャン、または複数行の読み取り
読み取りは行レベルでアトミックに処理されます。つまり、行の読み取りリクエストを送信すると、Bigtable は行全体を返すか、リクエストが失敗した場合は行を返しません。行の一部は、明示的にリクエストしない限り返されません。
API を直接呼び出すのではなく、Cloud Bigtable クライアント ライブラリを使用してテーブルからデータを読み取ることを強くおすすめします。読み取りリクエストを送信する方法を示すコードサンプルは、複数の言語でご利用いただけます。すべての読み取りリクエストは ReadRows
API 呼び出しを行います。
Data Boost サーバーレス コンピューティングを使用したデータの読み取り
Bigtable Data Boost を使用すると、毎日のアプリケーション トラフィックに影響を与えることなく、バッチ読み取りジョブとクエリを実行できます。Data Boost は、コア アプリケーションがコンピューティングにクラスタのノードを使用している間、Bigtable データを読み取るために使用できるサーバーレス コンピューティング サービスです。
Data Boost はスキャンに適していますが、単一行の読み取りにはおすすめしません。リバース スキャンには Data Boost を使用できません。詳細と利用条件については、Data Boost の概要をご覧ください。
単一行の読み取り
行キーに基づいて単一行をリクエストできます。単一行読み取り(ポイント読み取り)は Data Boost と互換性がありません。コードサンプルは次のバリエーションでご利用いただけます。
スキャン
スキャンは、Bigtable データを読み取る最も一般的な方法です。行キー接頭辞を指定するか、行キーの先頭と末尾を指定することで、Bigtable から連続する行の範囲または複数の行の範囲を読み取ることができます。コードサンプルは次のバリエーションでご利用いただけます。
リバース スキャン
リバース スキャンでは、行キー接頭辞または行の範囲を指定して、行の範囲を逆方向に読み取ることができます。行キー接頭辞は、逆方向に読み取るスキャンの開始点として使用されます。行の範囲を指定すると、終了行キーがスキャンの開始点として使用されます。
逆順でのスキャンは次のような場合に便利です。
- イベント(行)を見つけて、それから前の N 個のイベントを読み取る必要がある。
- 特定の値の前にある最大値を見つけます。これは、タイムスタンプを行キーのサフィックスとして使用して時系列データを保存する場合に有用です。
リバース スキャンは、フォワード スキャンよりも効率的ではありません。通常は、ほとんどのスキャンが転送されるように行キーを設計します。50 行以下の短いスキャンの場合は、リバース スキャンを使用して、低レイテンシの応答時間を維持します。
逆方向にスキャンするには、ReadRowsRequest
フィールドの reversed
の値を true に設定します。デフォルト値は false です。
次のクライアント ライブラリを使用するときにリバース スキャンを使用できます。
- C++ バージョン 2.18.0 以降の Bigtable クライアント ライブラリ
- Go バージョン 1.21.0 以降の Bigtable クライアント ライブラリ
- Java バージョン 2.24.1 以降の Bigtable クライアント ライブラリ
- Java バージョン 2.10.0 以降の Bigtable HBase クライアント ライブラリ
リバース スキャンの使用方法を示すコードサンプルについては、逆方向にスキャンするをご覧ください。
ユースケースの例
次の例は、リバース スキャンを使用して、顧客が最後にパスワードを変更したときと、特定の日前後の製品の価格変動を見つける方法を示しています。
パスワードの再設定
行キーのそれぞれにお客様 ID と日付が 123ABC#2022-05-02
形式で含まれており、列の 1 つがパスワードがリセットされた時刻を格納する 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`
お客様 ID 123ABC
が最後にパスワードを再設定した日を確認する場合は、今日の日付または将来の日付を使用して、123ABC#
~123ABC#<DATE>
の範囲を、列 password_reset
を含むすべての行を行数 1 で逆順にスキャンします。
価格の変更
この例では、行キーに商品、モデル、タイムスタンプの値が含まれ、列の 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 行分のフォワード スキャンを行い、同じ行から同じ行数のリバース スキャンを行います。この 2 つのスキャンにより、指定された時間の前後の料金がわかります。
フィルタ後の読み取り
特定の値を格納する行または行の一部のみが必要な場合は、読み取りリクエストでフィルタを使用できます。フィルタを使用すると、必要なデータを詳細に選択できます。
また、フィルタを使用すると、テーブルが使用しているガベージ コレクション ポリシーに読み取りが一致するようにできます。これは、タイムスタンプ付きの新しいセルを既存の列に頻繁に書き込む場合に特に有用です。ガベージ コレクションでは期限切れとなったデータが削除されるまでに最大 1 週間かかるため、タイムスタンプの範囲フィルタを使用してデータを読み取ることで、必要以上にデータが読み取られることを防止できます。
フィルタの概要では、使用できるフィルタの種類について詳しく説明しています。フィルタの使用では複数の言語で例を示しています。
承認済みビューからデータを読み取る
承認済みビューからデータを読み取るには、次のいずれかを使用する必要があります。
- gcloud CLI
- Java 用 Bigtable クライアント
他の Bigtable クライアント ライブラリでは、表示権限はまだサポートされていません。
Bigtable Data API の ReadRows
メソッドまたは SampleRowKeys
メソッドを呼び出すすべてのメソッドがサポートされています。クライアントの作成時に、テーブルの ID に加えて承認済みビューの ID を指定します。
読み取りとパフォーマンス
フィルタを使用する読み取りは、フィルタなしの読み取りよりも実行速度が低下し、CPU 使用率が増大します。一方、返されるデータの量を制限することで、使用するネットワーク帯域幅の量を大幅に削減できます。 一般に、フィルタはレイテンシではなくスループット効率を制御するために使用します。
読み取りパフォーマンスを最適化するには、次の方法を検討してください。
行セットを可能な限り制限します。ノードがスキャンしなければならない行数を制限することは、最初のバイトまでの時間と全体的なクエリ レイテンシを改善するための最初のステップです。行セットを制限しない場合、Bigtable はほぼ確実にテーブル全体をスキャンする必要があります。そのため、最もよく使用されるクエリがこのように機能するようスキーマを設計することをおすすめします。
行セットを制限した後にパフォーマンスをさらに調整するには、基本フィルタの追加を試みます。列のセットまたは返されるバージョンの数を制限すると、一般にレイテンシは増大せず、場合によっては Bigtable は各行の過去の無関係なデータを効率的にシークできます。
最初の 2 つの方法を実施した後でさらに読み取りパフォーマンスを調整する場合は、より複雑なフィルタの使用を検討してください。これを試すことについては、次のような理由が考えられます。
- 依然として不要なデータが大量に返される。
- クエリを Bigtable に push することで、アプリケーション コードを簡素化する必要があります。
ただし、大きな値に対して条件、インターリーブ、正規表現一致を必要とするフィルタには、スキャン対象データのほとんどを一致結果として返す場合にメリットよりもデメリットが多くなる傾向が見られる点に留意してください。この問題は、クライアント側で大幅な節約には至らずに、クラスタの CPU 使用率が増加するという形で発生します。
これらの方法に加えて、1 つの読み取りリクエストで、多数の連続していない行キーや行範囲を読み取ることは避けてください。1 つのリクエストで何百もの行キーや行範囲をリクエストすると、Bigtable はテーブルをスキャンして、リクエストされた行を順番に読み取ります。この並列性の欠如が全体的なレイテンシに影響を与え、ホットノードが読み取られると、テール レイテンシの増加につながる場合があります。リクエストされた行の範囲が増えるほど、読み取りの完了に時間がかかります。このレイテンシが許容できない場合は、代わりに、取得する行範囲を小さくした同時リクエストを複数送信する必要があります。
一般に、1 つのリクエストでより多くの行範囲を読み取ると、スループットは最適化されますが、レイテンシはされません。複数の同時リクエストで小さい行範囲を読み取ると、レイテンシは最適化されますが、スループットはされません。レイテンシとスループットの適切なバランスを図ることは、アプリケーションの要件によって異なります。また、同時読み込みリクエストの数と 1 つのリクエストでの行範囲の数を調整することで、このバランスを取ることができます。
Large rows
Bigtable では、行のサイズが 256 MB に制限されていますが、誤ってその最大値を超過する場合があります。上限を超えた行を読み取る必要がある場合は、リクエストをページ分割して、cells per row limit
フィルタと cells per row offset
フィルタを使用します。ページ分割された読み取りリクエストの間に書き込みが開始された場合、読み取りはアトミックに実行されない可能性があります。
次のステップ
- 集計セルを使用してカウンタを実装する。
- フィルタの概要について確認する。
- フィルタの使用方法を示すコードサンプルを確認する。
- Bigtable に送信できる書き込みリクエストの種類について確認する。
- Bigtable エミュレータを使用する。