讀取統計資料

Spanner 提供內建資料表,可儲存讀取作業的統計資料。您可以使用 SQL 陳述式從這些 SPANNER_SYS.READ_STATS* 資料表擷取統計資料。

讀取統計資料的使用時機

讀取統計資料可深入瞭解應用程式使用資料庫的方式,有助於調查效能問題。舉例來說,您可以查看針對資料庫執行的讀取形狀、執行頻率,並說明這些讀取形狀的效能特徵。您可以利用資料庫的讀取統計資料,找出導致 CPU 用量偏高的讀取形狀。從高層次來看,讀取統計資料可協助您瞭解資料庫的資源用量,進而掌握流量行為。

限制

  • 這項工具最適合用於分析類似的讀取資料串流,這些資料串流佔據大部分的 CPU 使用量。不適合用於搜尋只執行一次的讀取作業。

  • 這些統計資料追蹤的 CPU 使用量代表 Spanner 伺服器端的 CPU 使用量,不包括預先擷取 CPU 使用量和其他一些額外負擔。

  • 系統會盡可能收集統計資料。因此,如果基礎系統發生問題,可能會導致統計資料遺漏。舉例來說,如果發生內部網路問題,可能會遺漏部分統計資料。

查看閱讀統計資料

Spanner 會在 SPANNER_SYS 結構定義中提供讀取統計資料。您可以透過下列方式存取 SPANNER_SYS 資料:

  • Google Cloud 控制台中的資料庫 Spanner Studio 頁面。

  • gcloud spanner databases execute-sql 指令。

  • executeSqlexecuteStreamingSql 方法。

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` 會與該標記字串相符。
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 Spanner 在間隔期間執行讀取形狀的次數。
AVG_ROWS FLOAT64 讀取作業傳回的平均列數。
AVG_BYTES FLOAT64 讀取作業傳回的平均資料位元組數,不包含傳輸編碼額外負荷。
AVG_CPU_SECONDS FLOAT64 執行讀取作業的平均 Spanner 伺服器端 CPU 秒數,不含預先擷取 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 讀取作業在讀寫交易中執行的次數。 這一欄有助於判斷是否能將讀取作業移至唯讀交易,避免鎖定爭用。
AVG_DISK_IO_COST FLOAT64

這項查詢的平均費用 (以 Spanner HDD 磁碟負載計算)。

您可以使用這個值,比較在資料庫中執行的讀取作業之間的相對硬碟 I/O 費用。查詢 HDD 儲存空間中的資料時,系統會根據執行個體的 HDD 磁碟負載容量收費。值越高表示您使用的 HDD 磁碟負載越多,查詢速度可能比在 SSD 上執行時慢。此外,如果 HDD 磁碟負載已達上限,查詢效能可能會進一步受到影響。您可以監控執行個體的硬碟磁碟負載總容量,以百分比表示。如要增加 HDD 磁碟的負載容量,可以為執行個體新增更多處理單元或節點。詳情請參閱「變更運算容量」。如要提升查詢效能,也可以考慮將部分資料移至 SSD。

對於會耗用大量磁碟 I/O 的工作負載,建議您將經常存取的資料儲存在 SSD 儲存空間。從 SSD 存取的資料不會耗用 HDD 磁碟負載容量。您可以視需要將特定資料表、資料欄或次要索引儲存在 SSD 儲存空間,同時將不常存取的資料保留在 HDD 儲存空間。詳情請參閱「分層儲存空間總覽」。

查詢範例

本節包含多個擷取讀取統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫gcloud spannerGoogle Cloud 主控台執行這些 SQL 陳述式。

列出特定時間範圍內每個讀取形狀的基本統計資料

下列查詢會傳回最近 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 總使用率排序

下列查詢會傳回最近一小時內,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
  • 每個資料列都會包含指定間隔期間,資料庫上執行的所有讀取形狀的統計資料的匯總。每個時間間隔只有一個資料列。

  • SPANNER_SYS.READ_STATS_TOTAL_* 資料表中擷取的統計資料可能包含 Spanner 未在 SPANNER_SYS.READ_STATS_TOP_* 資料表中擷取的讀取形狀。

  • 這些表格中的部分資料欄會以 Cloud Monitoring 指標的形式顯示。 公開的指標如下:

    • 傳回的資料列數
    • 讀取執行次數
    • 讀取 CPU 時間
    • 鎖定延遲
    • 用戶端等待時間
    • 領導者重新整理延遲
    • 傳回的位元組數

    詳情請參閱「Spanner 指標」。

資料表結構定義

資料欄名稱 類型 說明
INTERVAL_END TIMESTAMP 包含的讀取形狀執行作業在發生時的時間間隔結束時間。
EXECUTION_COUNT INT64 Spanner 在間隔期間執行讀取形狀的次數。
AVG_ROWS FLOAT64 讀取作業傳回的平均列數。
AVG_BYTES FLOAT64 讀取作業傳回的平均資料位元組數,不包含傳輸編碼額外負荷。
AVG_CPU_SECONDS FLOAT64 執行讀取作業的平均 Spanner 伺服器端 CPU 秒數,不含預先擷取 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 陳述式。您可以使用用戶端程式庫gcloud spannerGoogle Cloud 主控台執行這些 SQL 陳述式。

找出所有讀取形狀的 CPU 總用量

下列查詢會傳回最近一小時內,讀取形狀所消耗的 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_MINUTESPANNER_SYS.READ_STATS_TOTAL_MINUTE:涵蓋前 6 個小時的間隔。

  • SPANNER_SYS.READ_STATS_TOP_10MINUTESPANNER_SYS.READ_STATS_TOTAL_10MINUTE:涵蓋前 4 天的間隔。

  • SPANNER_SYS.READ_STATS_TOP_HOURSPANNER_SYS.READ_STATS_TOTAL_HOUR:涵蓋前 30 天的間隔。

使用讀取統計資料排解 CPU 使用率偏高的問題

如果需要調查 Spanner 資料庫的 CPU 使用率偏高問題,或是想瞭解資料庫中耗用大量 CPU 的讀取形狀,Spanner 讀取統計資料就派得上用場。檢查使用大量資料庫資源的讀取形狀,可讓 Spanner 使用者有機會降低營運成本,並可能改善一般系統延遲。我們將透過下列步驟,說明如何使用讀取統計資料,調查資料庫中 CPU 使用率偏高的問題。

選取要調查的時間範圍

首先,請找出應用程式開始出現高 CPU 使用率的時間,舉例來說,在下列情境中,問題發生時間約為 2020 年 5 月 28 日下午 5:20。

收集所選時間範圍的讀取統計資料

選取開始調查的時間範圍後,我們會查看該時間範圍內 READ_STATS_TOTAL_10MINUTE 表格中收集的統計資料。這項查詢的結果可能會提供線索,讓我們瞭解 CPU 和其他讀取統計資料在該段時間內的變化。下列查詢會傳回 4:30 pm7: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

從這裡可以看出,avg_cpu_seconds 的平均 CPU 作業時間在醒目顯示的間隔中較高。interval_end 的值為 2020-05-28 19:20:00 的 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 排序的前三名讀取形狀相關資訊。請注意,我們在查詢中使用 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 使用率偏高的原因之一,可能是您開始更頻繁地執行幾個讀取形狀 (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 元件。

  • 如果您只進行讀取,而且可以使用單一讀取方法陳述讀取作業,您應使用單一讀取方法。單一讀取作業不像讀寫交易,不會鎖定。因此,如果沒有寫入資料,您應使用唯讀交易,而非成本較高的讀寫交易。

後續步驟