読み取りの統計情報

Spanner には、読み取りに関する統計情報を保存する組み込みテーブルが用意されています。SQL ステートメントを使用すると、これらの SPANNER_SYS.READ_STATS* テーブルから 統計情報を取得できます。

読み取りの統計情報を使用するタイミング

読み取りの統計情報からは、アプリケーションにおけるデータベースの使用状況に関する分析情報が得られます。これは、パフォーマンスの問題を調査する際に有用です。たとえば、データベースで実行されている読み取り形状、実行頻度を確認し、これらの読み取り形状のパフォーマンス特性を説明できます。データベースに関する読み取りの統計情報を使用して、CPU 使用率が上昇する読み取り形状を特定できます。概略的に述べると、読み取りの統計情報は、リソースの使用状況の観点からデータベースに送信されるトラフィックの動作を理解するうえで有用です。

制限事項

  • このツールは、ほとんどの CPU 使用率を考慮した類似する読み取りのストリームを分析する場合に最適です。1 回だけ実行された読み取りの検索には適していません。

  • これらの統計情報で追跡されている CPU 使用率は、プリフェッチの CPU 使用率とその他のオーバーヘッドを除く、Spanner サーバー側の CPU 使用率を表しています。

  • 統計情報は、ベスト エフォート ベースで収集されます。そのため、基盤となるシステムに問題がある場合、統計情報が失われる可能性があります。たとえば、内部ネットワークに問題がある場合、一部の統計情報が失われる可能性があります。

対象

SPANNER_SYS データは SQL インターフェースを介してのみ使用できます。例えば:

  • Google Cloud コンソールのデータベースの Spanner Studio ページ

  • gcloud spanner databases execute-sql コマンド

  • executeQueryAPI

Spanner が提供する他の単一読み取りメソッドは、SPANNER_SYS をサポートしていません。

CPU 使用率(読み取り形状別にグループ化)

次のテーブルでは、特定の期間中に CPU 使用率が最も高い読み取り形状が追跡されます。

  • SPANNER_SYS.READ_STATS_TOP_MINUTE: 1 分間隔で集計された読み取り形状の統計情報。
  • SPANNER_SYS.READ_STATS_TOP_10MINUTE: 10 分間隔で集計された読み取り形状の統計情報。
  • SPANNER_SYS.READ_STATS_TOP_HOUR: 1 時間間隔で集計された読み取り形状の統計情報。

これらのテーブルには以下のプロパティがあります。

  • 各テーブルには、テーブル名で指定された長さの、時間間隔が重複しないデータが含まれています。

  • 時間間隔は時刻に基づきます。1 分の間隔は現在の分が終わる際に終了し、10 分の間隔は正時に始まって 10 分ごとに終了し、1 時間の間隔は正時になるたびに終了します。各間隔が経過すると、Spanner はすべてのサーバーからデータを収集し、その後すぐに SPANNER_SYS テーブルでデータを使用できるようにします。

    たとえば、午前 11 時 59 分 30 秒に SQL クエリで使用可能な最新の時間間隔は次のとおりです。

    • 1 分: 午前 11:58:00~11:58:59
    • 10 分: 午前 11:40:00~11:49:59
    • 1 時間: 午前 10:00:00~10:59:59
  • Spanner は統計情報を読み取り形状でグループ化します。タグが存在する場合、FPRINT はタグのハッシュです。存在しない場合は、READ_COLUMNS 値のハッシュです。

  • 各行には、指定された期間中に Spanner が統計情報をキャプチャした特定の読み取り形状のすべての実行に関する統計情報が含まれています。

  • Spanner が期間中に実行された個別の読み取り形状に関するすべての情報を保存できない場合は、指定された期間中に最も高い CPU 使用率を記録した読み取り形状がシステムによって優先されます。

テーブル スキーマ

列名 説明
INTERVAL_END TIMESTAMP 含まれている読み取りが実行された時間間隔の終わり。
REQUEST_TAG STRING この読み取りオペレーションの省略可能なリクエストタグ。タグの使用の詳細については、リクエストタグによるトラブルシューティングをご覧ください。同じタグ文字列を持つ複数の読み取りの統計情報は、タグ文字列に一致する REQUEST_TAG がある 1 行にグループ化されます。
READ_TYPE STRING 読み取りが PARTITIONED_READREAD かを示します。PartitionRead API から取得した PartitionToken を使用した読み取りは、PARTITIONED_READ 読み取りタイプで表され、その他の読み取り API は READ で表されます。
READ_COLUMNS ARRAY<STRING> 読み取られた一連の列。これらはアルファベット順です。
FPRINT INT64 REQUEST_TAG 値のハッシュ(存在する場合)。存在しない場合は、READ_COLUMNS 値のハッシュ。
EXECUTION_COUNT INT64 Cloud Spanner が一定期間内に読み取り形状を実行した回数。
AVG_ROWS FLOAT64 読み取りから返された平均行数。
AVG_BYTES FLOAT64 送信エンコードのオーバーヘッドを除いた、読み取りから返されたデータの平均バイト数。
AVG_CPU_SECONDS FLOAT64 プリフェッチされた CPU とその他のオーバーヘッドを除いた、読み取りを実行する Spanner サーバー側の CPU 平均秒数。
AVG_LOCKING_DELAY_SECONDS FLOAT64 ロックを原因とする待機に費やした時間の平均秒数。
AVG_CLIENT_WAIT_SECONDS FLOAT64 Spanner が生成したデータをクライアントが直ちに使用しなかったことを原因とする待機に費やした時間の平均秒数。
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 すべての書き込みが観測された Paxos リーダーに対する確認を行うための待機に費やした時間の平均秒数。
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 読み取り / 書き込みトランザクションの一部として読み取りが実行された回数。この列は、読み取りを読み取り専用トランザクションに移動することで、ロック競合を回避できるかどうかを判断する際に有効です。

クエリの例

このセクションには、読み取りの統計情報を取得する SQL ステートメントの例がいくつか掲載されています。これらの SQL ステートメントは、クライアント ライブラリgcloud spanner、または Google Cloud Console を使用して実行できます。

特定の期間における各読み取り形状に関する基本統計を一覧表示する

次のクエリは、直前の 1 分間における上位読み取り形状の元データを返します。

SELECT fprint,
       read_columns,
       execution_count,
       avg_cpu_seconds,
       avg_rows,
       avg_bytes,
       avg_locking_delay_seconds,
       avg_client_wait_seconds
FROM spanner_sys.read_stats_top_minute
ORDER BY interval_end DESC LIMIT 3;
クエリ出力
fprint read_columns execution_count avg_cpu_seconds avg_rows avg_bytes avg_locking_delay_seconds avg_client_wait_seconds
125062082139 ["Singers.id", "Singers.name"] 8514387 0.000661355290396507 310.79 205 8.3232564943763752e-06 0
151238888745 ["Singers.singerinfo"] 3341542 6.5992827184280315e-05 12784 54 4.6859741349028595e-07 0
14105484 ["Albums.id", "Albums.title"] 9306619 0.00017855774721667873 1165.4 2964.71875 1.4328191393074178e-06 0

合計 CPU 使用率が最も高い順に読み取り形状を一覧表示する

次のクエリは、直近の 1 時間における CPU 使用率が最も高い読み取り形状を返します。

SELECT read_columns,
       execution_count,
       avg_cpu_seconds,
       execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.read_stats_top_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_top_hour)
ORDER BY total_cpu DESC LIMIT 3;
クエリ出力
read_columns execution_count avg_cpu_seconds total_cpu
["Singers.id", "Singers.name"] 1647 0.00023380297430622681 0.2579
["Albums.id", "Albums.title"] 720 0.00016738889440282034 0.221314999999999
["Singers.singerinfo""] 3223 0.00037764625882302246 0.188053

統計情報の集計

SPANNER_SYS には、特定の期間に Spanner によってキャプチャされた読み取りの統計情報の集計を格納するテーブルも含まれています。

  • SPANNER_SYS.READ_STATS_TOTAL_MINUTE: 1 分間隔におけるすべての読み取り形状の統計情報の集計。
  • SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: 10 分間隔におけるすべての読み取り形状の統計情報の集計。
  • SPANNER_SYS.READ_STATS_TOTAL_HOUR: 1 時間間隔におけるすべての読み取り形状の統計情報の集計。

統計情報の集計テーブルには次のプロパティがあります。

  • 各テーブルには、テーブル名で指定された長さの、時間間隔が重複しないデータが含まれています。

  • 時間間隔は時刻に基づきます。1 分の間隔は現在の分が終わるときに終了し、10 分の間隔は正時に始まって 10 分ごとに終了し、1 時間の間隔は正時になるたびに終了します。

    たとえば、午前 11 時 59 分 30 秒の時点で、読み取りの統計情報の集計に対する SQL クエリで使用可能な最新の間隔は次のとおりです。

    • 1 分: 午前 11:58:00~11:58:59
    • 10 分: 午前 11:40:00~11:49:59
    • 1 時間: 午前 10:00:00~10:59:59
  • 各行には、指定した期間中にデータベースに対して実行されたすべての読み取り形状の統計情報が集計されています。時間間隔ごとに 1 行のみとなります。

  • SPANNER_SYS.READ_STATS_TOTAL_* テーブルにキャプチャされた統計情報には、Spanner が SPANNER_SYS.READ_STATS_TOP_* テーブルにキャプチャしなかった読み取り形状が含まれている場合があります。

  • これらのテーブルの一部の列は、Cloud Monitoring で指標として公開されています。公開される指標は次のとおりです。

    • 返された行数
    • 読み取りの実行回数
    • 読み取り CPU 時間
    • ロックの遅延
    • クライアントの待機時間
    • リーダーの更新遅延
    • 返されたバイト数

    詳細については、Spanner の指標をご覧ください。

テーブル スキーマ

列名 説明
INTERVAL_END TIMESTAMP 含まれている読み取り形状が実行された時間間隔の終わり。
EXECUTION_COUNT INT64 Cloud Spanner が一定期間内に読み取り形状を実行した回数。
AVG_ROWS FLOAT64 読み取りから返された平均行数。
AVG_BYTES FLOAT64 送信エンコードのオーバーヘッドを除いた、読み取りから返されたデータの平均バイト数。
AVG_CPU_SECONDS FLOAT64 プリフェッチされた CPU とその他のオーバーヘッドを除いた、読み取りを実行する Spanner サーバー側の CPU 平均秒数。
AVG_LOCKING_DELAY_SECONDS FLOAT64 ロックを原因とする待機に費やした時間の平均秒数。
AVG_CLIENT_WAIT_SECONDS FLOAT64 スロットリングを原因とする待機に費やした時間の平均秒数。
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 マルチリージョン構成のインスタンス間における読み取りの調整に費やした時間の平均秒数。
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 読み取り / 書き込みトランザクションの一部として読み取りが実行された回数。この列は、一部の読み取りを読み取り専用トランザクションに移動することで、ロック競合を回避できるかどうかを判断する際に有効です。

クエリの例

このセクションには、読み取りの統計情報の集計を取得する SQL ステートメントの例がいくつか掲載されています。これらの SQL ステートメントは、クライアント ライブラリgcloud spanner、または Google Cloud Console を使用して実行できます。

すべての読み取り形状の合計 CPU 使用率を確認する

次のクエリは、直近の 1 時間で、読み取り形状によって消費された CPU 時間数を返します。

SELECT (avg_cpu_seconds * execution_count / 60 / 60)
  AS total_cpu_hours
FROM spanner_sys.read_stats_total_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_total_hour);
クエリ出力
total_cpu_hours
0.00026186111111111115

特定の期間における合計実行回数を確認する

次のクエリは、直近の 1 分間に実行された読み取り形状の総数を返します。

SELECT interval_end,
       execution_count
FROM spanner_sys.read_stats_total_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_total_minute);
クエリ出力
interval_end execution_count
2020-05-28 11:02:00-07:00 12861966

データの保持

Spanner は、少なくとも次の期間中に各テーブルのデータを保持します。

  • SPANNER_SYS.READ_STATS_TOP_MINUTE および SPANNER_SYS.READ_STATS_TOTAL_MINUTE: 過去 6 時間を対象とする間隔。

  • SPANNER_SYS.READ_STATS_TOP_10MINUTE および SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: 過去 4 日間を対象とするインターフェース。

  • SPANNER_SYS.READ_STATS_TOP_HOUR および SPANNER_SYS.READ_STATS_TOTAL_HOUR: 過去 30 日間を対象とする間隔。

読み取りの統計情報を使用した高 CPU 使用率についてのトラブルシューティングを実施する

Spanner の読み取り統計情報は、Spanner データベースにおける CPU 使用率が高いことについて調査する必要がある場合や、データベースで CPU 使用率の高い読み取り形状を把握しようとしている場合に有用です。大量のデータベース リソースを使用する読み取り形状を検査することは、Spanner ユーザーが運用コストを削減することにつながり、場合によっては一般的なシステム レイテンシを改善する方法として活用することが考えられます。次の手順では、読み取りの統計情報を使用してデータベースにおける高 CPU 使用率について調査する方法を説明します。

調査する期間を選択する

まず、アプリケーションでの CPU 使用率が高くなり始めた時間を探すことから調査を開始します。たとえば、次のシナリオでは、2020 年 5 月 28 日の午後 5 時 20 分頃に問題が発生し始めました。

選択した期間の読み取りの統計情報を収集する

調査を開始する期間を選択していただいている場合は、その時刻前後に READ_STATS_TOTAL_10MINUTE テーブルで収集された統計情報を確認いたします。このクエリの結果は、その期間中における CPU などの読み取り統計情報の変化についての手がかりになる可能性があります。次のクエリは、4:30 pm から 7:30 pm まで(両端を含む)の読み取り統計情報の集計結果を返します。

SELECT
  interval_end,
  ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
  execution_count,
  avg_locking_delay_seconds
FROM SPANNER_SYS.READ_STATS_TOTAL_10MINUTE
WHERE
  interval_end >= "2020-05-28T16:30:00"
  AND interval_end <= "2020-05-28T19:30:00"
ORDER BY interval_end;

次のデータは、クエリから返される結果の例です。

interval_end avg_cpu_seconds execution_count avg_locking_delay_seconds
2020-05-28 16:40:00-07:00 0.0004 11111421 8.3232564943763752e-06
2020-05-28 16:50:00-07:00 0.0002 8815637 8.98734051776406e-05
2020-05-28 17:00:00-07:00 0.0001 8260215 6.039129247846453e-06
2020-05-28 17:10:00-07:00 0.0001 8514387 9.0535466616680686e-07
2020-05-28 17:20:00-07:00 0.0006 13715466 2.6801485272173765e-06
2020-05-28 17:30:00-07:00 0.0007 12861966 4.6859741349028595e-07
2020-05-28 17:40:00-07:00 0.0007 3755954 2.7131391918005383e-06
2020-05-28 17:50:00-07:00 0.0006 4248137 1.4328191393074178e-06
2020-05-28 18:00:00-07:00 0.0006 3986198 2.6973481999639748e-06
2020-05-28 18:10:00-07:00 0.0006 3510249 3.7577083563017905e-06
2020-05-28 18:20:00-07:00 0.0004 3341542 4.0940589703795433e-07
2020-05-28 18:30:00-07:00 0.0002 8695147 1.9914494947583975e-05
2020-05-28 18:40:00-07:00 0.0003 11679702 1.8331461539001595e-05
2020-05-28 18:50:00-07:00 0.0003 9306619 1.2527332321222135e-05
2020-05-28 19:00:00-07:00 0.0002 8520508 6.2268448078447915e-06
2020-05-28 19:10:00-07:00 0.0006 13715466 2.6801485272173765e-06
2020-05-28 19:20:00-07:00 0.0005 11947323 3.3029114639321295e-05
2020-05-28 19:30:00-07:00 0.0002 8514387 9.0535466616680686e-07

上の図では、平均 CPU 時間 avg_cpu_secondsハイライト表示された期間に上昇しているのがわかります。値が 2020-05-28 19:20:00interval_end では CPU 時間が増大しているため、その期間を選択して次の手順で詳細な調査を行います。

CPU 使用率が高い原因となる読み取り形状を確認する

もう少し掘り下げて、ここでは READ_STATS_TOP_10MINUTE テーブルに対してクエリを実行し、前の手順で選択した期間についてのデータを取得します。このクエリの結果は、高 CPU 使用率の原因となっている読み取り形状を特定するうえで有用です。

SELECT
  read_columns,
  ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
  execution_count,
  avg_rows
FROM SPANNER_SYS.READ_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-28T19:20:00"
ORDER BY avg_cpu_seconds DESC LIMIT 3;

クエリから返される結果の例として次のデータは、avg_cpu_seconds によってランキングされた上位 3 つの読み取り形状に関する情報を返しています。クエリで ROUND を使用して、avg_cpu_seconds の出力を小数点以下 4 桁に制限していることに注目してください。

read_columns avg_cpu_seconds execution_count avg_rows
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.shares]1 0.4192 1182 11650.42216582
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.likes,globalTagAffinity.score] 0.0852 4 12784
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.ugcCount] 0.0697 1140 310.7921052631

1 _exists は、特定の行が存在するかどうかを確認するために使用する内部フィールドです。

CPU 使用率が上昇する理由の 1 つには、いくつかの読み取り形状についてより高い頻度での実行(execution_count)を開始したことが考えられます。おそらく、読み取りによって返された平均行数(avg_rows)が増加しています。読み取り形状のこれらのプロパティのいずれからも原因が特定できない場合は、avg_locking_delay_secondsavg_client_wait_secondsavg_bytes などの他のプロパティを調べます。

高い CPU 使用率を低減するためのベスト プラクティスを適用する

前述の手順を完了したら、これらのベスト プラクティスのいずれかを適用することで、状況に対処することを検討してください。

  • Spanner が期間内に読み取り形状を実行した回数は、測定値が妥当な結果、または問題の兆候のいずれであるかを示すベースラインを必要とする指標の良い例です。指標のベースラインを設定すると、通常の動作からの予期しない逸脱の原因を検出して調査することができます。

  • ほとんどの場合に CPU 使用率が比較的安定しているものの、突発的な上昇が見られ、こうした上昇について類似したユーザー リクエストの突発的な増大またはアプリケーションの動作との相関関係が認められる場合は、すべて想定どおりに動作していることを示している可能性があります。

  • 次のクエリを試し、Spanner が各読み取り形状を実行した回数でランク付けした上位の読み取り形状を特定します。

    SELECT interval_end, read_columns, execution_count
    FROM SPANNER_SYS.READ_STATS_TOP_MINUTE
    ORDER BY execution_count DESC
    LIMIT 10;
    
  • レイテンシについて、特にマルチリージョン インスタンス構成を使用している場合に、可能な限り低い読み取りレイテンシを特定するには、強力な読み取りの代わりにステイル読み取りを使用して、読み取りレイテンシの AVG_LEADER_REFRESH_DELAY_SECONDS コンポーネントを削減または削除します。

  • 読み取りのみを行い、単一読み取りメソッドを使用して読み取りを表現できる場合は、その単一読み取りメソッドを使用する必要があります。単一読み取りは、読み取り / 書き込みトランザクションとは異なり、ロックしません。そのため、データの書き込みを行わない場合は、高コストの読み取り / 書き込みトランザクションよりも読み取り専用トランザクションを使用する必要があります。

次のステップ