Spanner 提供內建資料表,用於儲存讀取相關的統計資料。您可以使用 SQL 陳述式從這些 SPANNER_SYS.READ_STATS*
資料表擷取統計資料。
使用讀取統計資料的時機
讀取統計資料可讓您瞭解應用程式如何使用資料庫,並在調查效能問題時提供實用資訊。舉例來說,您可以查看資料庫執行哪些讀取形狀、執行頻率,並說明這些讀取形狀的效能特徵。您可以使用資料庫的讀取統計資料,找出導致 CPU 用量偏高的讀取形狀。大致來說,讀取統計資料有助於您瞭解資料庫中流量在資源用量方面的行為。
限制
這項工具最適合用於分析占 CPU 用量大部分的類似讀取作業串流。這對於搜尋僅執行一次的讀取作業並不理想。
這些統計資料中追蹤的 CPU 用量代表 Spanner 伺服器端 CPU 用量,不含預先擷取 CPU 用量和其他一些額外開銷。
系統會盡力收集統計資料。因此,如果基礎系統發生問題,統計資料可能會遺漏。舉例來說,如果發生內部網路問題,系統可能會遺漏部分統計資料。
可用性
SPANNER_SYS
資料只能透過 SQL 介面取得,例如:
Google Cloud 控制台中資料庫的 Spanner Studio 頁面
gcloud spanner databases execute-sql
指令executeQuery
API
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_READ 還是 READ 。使用從 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 磁碟負載而言,這項查詢的平均成本。 您可以使用這個值,比較資料庫中讀取作業的相對 HDD I/O 成本。查詢 HDD 儲存空間中的資料時,系統會根據執行個體的 HDD 磁碟負載容量向您收費。值越高,表示您使用較多 HDD 磁碟負載,且查詢速度可能會比在 SSD 上執行時慢。此外,如果硬碟磁碟負載已達上限,查詢效能可能會進一步受到影響。您可以監控執行個體的總HDD 磁碟負載容量百分比。如要增加 HDD 磁碟負載容量,您可以為執行個體新增更多處理單元或節點。詳情請參閱「變更運算容量」。如要改善查詢效能,請考慮將部分資料移至 SSD。 如果工作負載會大量使用磁碟 I/O,建議您將經常存取的資料儲存在 SSD 儲存空間中。從 SSD 存取的資料不會耗用 HDD 磁碟的負載容量。您可以視需要將特定資料表、資料欄或次要索引儲存在 SSD 儲存空間,同時將不常存取的資料儲存在 HDD 儲存空間。詳情請參閱分層儲存空間總覽。 |
查詢範例
本節包含多個擷取讀取統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫、gcloud spanner 或 Google 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 spanner 或 Google 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_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 資料庫的 CPU 使用率過高,或是想瞭解資料庫的 CPU 讀取形狀,Spanner 讀取統計資料就會派上用場。檢查使用大量資料庫資源的讀取形狀,可讓 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:00 的 interval_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
排名的前三個讀取形狀。請注意,我們在查詢中使用 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_seconds
、avg_client_wait_seconds
或 avg_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
元件。如果您只進行讀取,而且可以使用單一讀取方法陳述讀取作業,您應使用單一讀寫方法。單一讀取作業不會鎖定,這與讀寫交易不同。因此,如果您未寫入資料,應使用唯讀交易,而非較耗費的讀寫交易。
後續步驟
- 瞭解其他內省工具。
- 瞭解 Spanner 為每個資料庫儲存的其他資訊。這些資訊儲存在資料庫的資訊結構定義資料表中。
- 進一步瞭解 Spanner 的 SQL 最佳做法。
- 進一步瞭解如何調查 CPU 使用率偏高的問題。