Spanner 提供一組內建統計資料表,協助您深入瞭解查詢、讀取和交易。如要將統計資料與應用程式碼建立關聯,並改善疑難排解作業,您可以在應用程式碼中,將標記 (任意形式的字串) 新增至 Spanner 的讀取、查詢和交易作業。這些標記會填入統計資料表,協助您根據標記進行關聯和搜尋。
Spanner 支援兩種標記:要求標記和交易標記。顧名思義,您可以將交易代碼加到交易中,並將要求代碼加到個別查詢和讀取 API。您可以在交易範圍設定交易標記,並為交易中的每個適用 API 要求設定個別要求標記。應用程式程式碼中設定的要求標記和交易標記,會填入下列統計資料表的資料欄。
| 統計資料表 | 統計資料表中填入的代碼類型 |
|---|---|
| TopN 查詢統計資料 | 要求標記 |
| TopN 讀取統計資料 | 要求標記 |
| 前 N 項交易統計資料 | 交易代碼 |
| TopN 鎖定統計資料 | 交易標記 |
要求標記
您可以為查詢或讀取要求新增選用要求標記。
Spanner 會依要求標記將統計資料分組,這項資訊會顯示在「查詢統計資料」和「讀取統計資料」表格的 REQUEST_TAG 欄位中。
使用請求標記的時機
以下列舉幾個適合使用請求標記的情境。
- 找出有問題的查詢或讀取作業來源: Spanner 會在內建統計資料表中收集讀取和查詢的統計資料。在統計資料表中發現查詢速度緩慢或讀取作業耗用大量 CPU 時,如果已為這些作業指派標記,即可根據標記中的資訊,找出呼叫這些作業的來源 (應用程式/微服務)。
- 在統計資料表中找出讀取或查詢:指派要求標記有助於根據您感興趣的標記,篩選統計資料表中的資料列。
- 找出特定應用程式或微服務的查詢是否緩慢:要求標記有助於判斷特定應用程式或微服務的查詢是否延遲時間較長。
- 一組讀取或查詢的統計資料分組:您可以使用要求標記,追蹤、比較及回報一組類似讀取或查詢的成效。舉例來說,如果多個查詢項目存取資料表或一組資料表時,存取模式相同,您可以考慮為所有這些查詢項目新增相同標記,以便一起追蹤。
如何指派要求標記
以下範例顯示如何使用 Spanner 用戶端程式庫設定要求標記。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
如何在統計資料表中查看要求標記
下列查詢會傳回每 10 分鐘間隔的查詢統計資料。
SELECT t.text,
t.request_tag,
t.execution_count,
t.avg_latency_seconds,
t.avg_rows,
t.avg_bytes
FROM SPANNER_SYS.QUERY_STATS_TOP_10MINUTE AS t
LIMIT 3;
我們以查詢傳回的下列資料為例。
| 文字 | request_tag | execution_count | avg_latency_seconds | avg_rows | avg_bytes |
|---|---|---|---|---|---|
| SELECT SingerId, AlbumId, AlbumTitle FROM Albums | app=concert,env=dev,action=select | 212 | 0.025 | 21 | 2365 |
| select * from orders; | app=catalogsearch,env=dev,action=list | 55 | 0.02 | 16 | 33.35 |
| SELECT SingerId, FirstName, LastName FROM Singers; | [empty string] | 154 | 0.048 | 42 | 486.33 |
從這個結果表格中,我們可以發現,如果您為查詢指派 REQUEST_TAG,系統就會在統計資料表中填入該值。如果沒有指派任何要求標記,系統會顯示空白字串。
如果是已加上標記的查詢,系統會依標記匯總統計資料 (例如,要求標記 app=concert,env=dev,action=select 的平均延遲時間為 0.025 秒)。如果沒有指派任何標記,系統會依查詢彙整統計資料 (例如第三列的查詢平均延遲時間為 0.048 秒)。
交易標記
您可以視需要為個別交易新增交易標記。
Spanner 會依交易代碼將統計資料分組,這項代碼會顯示在交易統計資料表的 TRANSACTION_TAG 欄位中。
交易代碼的使用時機
以下列舉幾個適合使用交易代碼的情境。
- 找出問題交易的來源:Spanner 會在交易統計資料表中收集讀寫交易的統計資料。在交易統計資料表中發現交易速度緩慢時,如果已為這些交易指派標記,即可根據標記中的資訊,找出呼叫這些交易的來源 (應用程式/微服務)。
- 在統計資料表中找出交易:指派交易代碼有助於根據您感興趣的代碼,篩選交易統計資料表中的資料列。如果沒有交易代碼,要找出統計資料代表的作業可能相當麻煩。舉例來說,如要查看交易統計資料,您必須檢查相關資料表和資料欄,找出未標記的交易。
- 找出特定應用程式或微服務的交易是否緩慢:交易標記有助於找出特定應用程式或微服務的交易是否延遲時間較長。
- 一組交易的統計資料:您可以使用交易代碼追蹤、比較及回報一組類似交易的成效。
- 找出存取鎖定衝突所涉資料欄的交易:交易標記有助於在「鎖定統計資料」表格中,找出導致鎖定衝突的個別交易。
- 使用變更串流,將使用者變更資料從 Spanner 串流輸出:變更串流資料記錄包含修改使用者資料的交易交易標記。這可讓變更串流的讀取器根據標記,將變更與交易類型建立關聯。
如何指派交易標記
以下範例顯示如何使用 Spanner 用戶端程式庫設定交易標記。使用用戶端程式庫時,您可以在交易呼叫開始時設定交易標記,並套用至該交易中的所有個別作業。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
如何在交易統計資料表中查看交易代碼
下列查詢會傳回每隔 10 分鐘的交易統計資料。
SELECT t.fprint,
t.transaction_tag,
t.read_columns,
t.commit_attempt_count,
t.avg_total_latency_seconds
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE AS t
LIMIT 3;
我們以查詢傳回的下列資料為例。
| fprint | transaction_tag | read_columns | commit_attempt_count | avg_total_latency_seconds |
|---|---|---|---|---|
| 40015598317 | app=concert,env=dev | [Venues._exists, Venues.VenueId, Venues.VenueName, Venues.Capacity] |
278802 | 0.3508 |
| 20524969030 | app=product,service=payment | [Singers.SingerInfo] | 129012 | 0.0142 |
| 77848338483 | [empty string] | [Singers.FirstName, Singers.LastName, Singers._exists] | 5357 | 0.048 |
從這個結果表格中,我們可以發現如果已將 TRANSACTION_TAG 指派給交易,則交易統計資料表格中會填入該 TRANSACTION_TAG。如果沒有指派交易代碼,系統會顯示空白字串。
系統會根據交易標記匯總統計資料 (例如,交易標記 app=concert,env=dev a 的平均延遲時間為 0.3508 秒)。如果沒有指派標記,系統會依 FPRINT 匯總統計資料 (例如第三列的 77848338483 平均延遲時間為 0.048 秒)。
如何在鎖定統計資料表中查看交易代碼
下列查詢會傳回每 10 分鐘的鎖定統計資料。
CAST() 函式會將 row_range_start_key BYTES 欄位轉換為 STRING。
SELECT
CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
s.lock_wait_seconds,
s.sample_lock_requests
FROM SPANNER_SYS.LOCK_STATS_TOP_10MINUTE s
LIMIT 2;
我們以查詢傳回的下列資料為例。
| row_range_start_key | lock_wait_seconds | sample_lock_requests |
|---|---|---|
| 歌曲(2,1,1) | 0.61 | LOCK_MODE: ReaderShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=product,service=shipping LOCK_MODE: WriterShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=product,service=payment |
| 專輯(2 張以上) | 0.48 | LOCK_MODE: ReaderShared COLUMN: users._exists1 TRANSACTION_TAG: [empty string] LOCK_MODE: WriterShared COLUMN: users._exists TRANSACTION_TAG: [empty string] |
從這個結果表格中,我們可以看到,如果您已將 TRANSACTION_TAG 指派給交易,則該交易會填入鎖定統計資料表。如果沒有指派交易代碼,系統會顯示空白字串。
API 方法與要求/交易標記之間的對應關係
要求標記和交易標記適用於特定 API 方法,視交易模式為唯讀交易或讀寫交易而定。一般來說,交易標記適用於讀寫交易,要求標記則適用於唯讀交易。下表顯示 API 方法與適用標記類型的對應關係。
| API 方法 | 交易模式 | 要求標記 | 交易代碼 |
|---|---|---|---|
| Read、 StreamingRead |
唯讀交易 | 是 | 否 |
| 讀寫交易 | 是 | 是 | |
| ExecuteSql、 ExecuteStreamingSql1 |
唯讀交易1 | 有1 | 否 |
| 讀寫交易 | 是 | 是 | |
| ExecuteBatchDml | 讀寫交易 | 是 | 是 |
| BeginTransaction | 讀寫交易 | 否 | 是 |
| 修訂版本 | 讀寫交易 | 否 | 是 |
1 如果是使用 Apache Beam SpannerIO Dataflow 連接器執行的變更串流查詢,REQUEST_TAG 會包含 Dataflow 工作名稱。
限制
為讀取、查詢和交易作業新增標記時,請注意下列限制:
- 標記字串長度不得超過 50 個字元。超過這個上限的字串會遭到截斷。
- 標記只能使用 ASCII 字元 (32-126)。任意 Unicode 字元都會替換成底線。
- 系統會從字串中移除任何開頭底線 (_) 字元。
- 標記須區分大小寫。舉例來說,如果您在一組查詢中加入要求標記
APP=cart,ENV=dev,並在另一組查詢中加入app=cart,env=dev,Spanner 會分別匯總每個標記的統計資料。 在下列情況下,統計資料表可能不會顯示標記:
- 如果 Spanner 無法將間隔期間執行的所有已標記作業的統計資料儲存在資料表中,系統會優先處理在指定間隔期間消耗最多資源的作業。
標記命名
為資料庫作業指派標記時,請務必考量您想在每個標記字串中傳達的資訊。選擇適當的慣例或模式,可讓標記發揮更大效用。舉例來說,適當的標記命名可讓您更輕鬆地將統計資料與應用程式碼建立關聯。
您可以在上述限制內選擇任何標記。不過,我們建議您將標記字串建構為以半形逗號分隔的鍵/值組合。
舉例來說,假設您使用 Spanner 資料庫處理電子商務用途。您可能想在要指派給特定查詢的要求標記中,加入應用程式、開發環境和查詢所採取的動作等相關資訊。您可以考慮以鍵/值格式指派標籤字串,例如 app=cart,env=dev,action=update。這表示查詢是從開發環境中的購物車應用程式呼叫,並用於更新購物車。
假設您有來自目錄搜尋應用程式的其他查詢,並將標記字串指派為 app=catalogsearch,env=dev,action=list。現在,如果查詢統計資料表中的任何查詢顯示為高延遲查詢,您可以使用標記輕鬆找出來源。
以下舉例說明如何使用標記模式整理作業統計資料。這些範例僅供參考,您也可以使用逗號等分隔符號,在代碼字串中合併這些範例。
| 標記鍵 | 標記/值組合範例 | 說明 |
|---|---|---|
| 應用程式 | app=cart app=frontend app=catalogsearch |
有助於識別呼叫作業的應用程式。 |
| 環境 | env=prod env=dev env=test env=staging |
有助於識別與作業相關聯的環境。 |
| 架構 | framework=spring framework=django framework=jetty |
有助於識別與作業相關聯的架構。 |
| 動作 | action=list action=retrieve action=update |
有助於識別作業採取的動作。 |
| 服務 | service=payment service=shipping |
有助於識別呼叫作業的微服務。 |
注意事項
- 指派
REQUEST_TAG後,查詢統計資料表會將具有相同標記字串的多個查詢統計資料,歸類在同一列。TEXT欄位只會顯示其中一個查詢的文字。 - 指派
REQUEST_TAG時,讀取統計資料表格會將具有相同標記字串的多個讀取作業統計資料,歸類在同一列。讀取的所有資料欄都會新增至READ_COLUMNS欄位。 - 指派
TRANSACTION_TAG後,交易統計資料表格會將具有相同標記字串的交易統計資料歸為同一列。交易寫入的所有資料欄集會新增至WRITE_CONSTRUCTIVE_COLUMNS欄位,讀取的所有資料欄集則會新增至READ_COLUMNS欄位。
使用標記排解問題情境
找出有問題的交易來源
下列查詢會傳回所選時間範圍內,前幾名交易的原始資料。
SELECT
fprint,
transaction_tag,
ROUND(avg_total_latency_seconds,4) as avg_total_latency_sec,
ROUND(avg_commit_latency_seconds,4) as avg_commit_latency_sec,
commit_attempt_count,
commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC;
下表列出查詢傳回的範例資料,其中有三個應用程式 (分別是 cart、product 和 frontend) 擁有或查詢相同的資料庫。
找出延遲時間較長的交易後,您可以使用相關聯的標記,找出應用程式程式碼的相關部分,並使用交易統計資料進一步排解問題。
| fprint | transaction_tag | avg_total_latency_sec | avg_commit_latency_sec | commit_attempt_count | commit_abort_count |
|---|---|---|---|---|---|
| 7129109266372596045 | app=cart,service=order | 0.3508 | 0.0139 | 278802 | 142205 |
| 9353100217060788102 | app=cart,service=redis | 0.1633 | 0.0142 | 129012 | 27177 |
| 9353100217060788102 | app=product,service=payment | 0.1423 | 0.0133 | 5357 | 636 |
| 898069986622520747 | app=product,service=shipping | 0.0159 | 0.0118 | 4269 | 1 |
| 9521689070912159706 | app=frontend,service=ads | 0.0093 | 0.0045 | 164 | 0 |
| 11079878968512225881 | [empty string] | 0.031 | 0.015 | 14 | 0 |
同樣地,您也可以使用要求標記,從查詢統計資料表找出有問題的查詢來源,以及從讀取統計資料表找出有問題的讀取來源。
找出特定應用程式或微服務的交易延遲和其他統計資料
如果您在標記字串中使用應用程式名稱或微服務名稱,有助於依含有該應用程式名稱或微服務名稱的標記,篩選交易統計資料表。
假設您已在付款應用程式中新增交易,並想查看這些新交易的延遲時間和其他統計資料,如果標記中含有付款應用程式名稱,您可以篩選交易統計資料表,只顯示含有 app=payment 的標記。
下列查詢會傳回付款應用程式的交易統計資料,間隔為 10 分鐘。
SELECT
transaction_tag,
avg_total_latency_sec,
avg_commit_latency_sec,
commit_attempt_count,
commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE STARTS_WITH(transaction_tag, "app=payment")
LIMIT 3;
以下是輸出內容範例:
| transaction_tag | avg_total_latency_sec | avg_commit_latency_sec | commit_attempt_count | commit_abort_count |
|---|---|---|---|---|
| app=payment,action=update | 0.3508 | 0.0139 | 278802 | 142205 |
| app=payment,action=transfer | 0.1633 | 0.0142 | 129012 | 27177 |
| app=payment, action=retrieve | 0.1423 | 0.0133 | 5357 | 636 |
同樣地,您也可以使用要求標記,在查詢統計資料或讀取統計資料表中,找出特定應用程式的查詢或讀取作業。
找出涉及鎖定衝突的交易
如要找出鎖定等待時間較長的交易和資料列鍵,請查詢 LOCK_STAT_TOP_10MINUTE 表格,其中列出涉及鎖定衝突的資料列鍵、資料欄和相應交易。
SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
t.total_lock_wait_seconds,
s.lock_wait_seconds,
s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
s.sample_lock_requests
FROM spanner_sys.lock_stats_total_10minute t, spanner_sys.lock_stats_top_10minute s
WHERE
t.interval_end = "2020-05-17T18:40:00" and s.interval_end = t.interval_end;
以下是查詢的輸出範例:
| row_range_start_key | total_lock_wait_seconds | lock_wait_seconds | frac_of_total | sample_lock_requests |
|---|---|---|---|---|
| 歌手(32) | 2.37 | 1.76 | 1 | LOCK_MODE: WriterShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=cart,service=order LOCK_MODE: ReaderShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=cart,service=redis |
從這個結果表格中,我們可以看到 Singers 資料表在鍵 SingerId=32 發生衝突。Singers.SingerInfo 是指 ReaderShared 和 WriterShared 之間發生鎖定衝突的資料欄。您也可以找出發生衝突的對應交易 (app=cart,service=order 和 app=cart,service=redis)。
找出造成鎖定衝突的交易後,您現在可以使用「交易統計資料」專注處理這些交易,進一步瞭解交易的運作方式,以及是否能避免衝突或縮短鎖定時間。詳情請參閱「減少鎖定爭用的最佳做法」。
後續步驟
- 瞭解其他內省工具。
- 瞭解 Spanner 為每個資料庫儲存的其他資訊。這些資訊儲存在資料庫的資訊結構定義資料表中。
- 進一步瞭解 Spanner 適用的 SQL 最佳做法。
- 進一步瞭解如何調查 CPU 使用率偏高問題。