本頁面概略說明 Spanner 逾時錯誤:說明其定義、發生原因,以及如何排解及解決這些錯誤。
存取 Spanner API 時,要求可能會因 DEADLINE_EXCEEDED
錯誤而失敗。這項錯誤表示在設定的逾時期限內未收到回應。
超出期限錯誤可能由許多不同原因造成,例如 Spanner 例項超載、未最佳化的結構定義或未最佳化的查詢。本頁說明發生逾時錯誤的常見情境,並提供調查及解決這些問題的指南。
Spanner 的期限和重試原則
Spanner 的期限和重試原則與許多其他系統不同。在 Spanner 中,您應指定逾時期限,也就是回應有效的最大時間長度。我們不建議您為了立即再次重試相同的作業而人為縮短期限,因為這可能導致作業永遠無法完成。在這種情況下,我們不建議採用下列策略和作業,因為這會適得其反,並破壞 Spanner 的內部重試行為:
設定的期限過短。也就是說,作業無法在逾時前完成,且無法在偶發的尾端延遲時間增加時恢復。請改為設定期限,也就是回覆內容的有效期限上限。
設定過長的期限,並在期限到期前取消作業。這會導致重試,並在每次嘗試時浪費工作。這可能會為執行個體帶來大量額外負載。
什麼是逾時錯誤?
使用 Spanner 用戶端程式庫時,底層 gRPC 層會負責通訊、管理、解管理,以及強制執行期限。應用程式可透過期限指定等待要求完成所需的時間長度,如果超過期限,要求就會終止並顯示超出期限的錯誤。
逾時設定指南說明如何在每個支援的 Spanner 用戶端程式庫中指定期限 (或逾時)。Spanner 用戶端程式庫會使用預設的逾時和重試政策設定,這些設定會在下列設定檔中定義:
- spanner_grpc_service_config.json
- spanner_admin_instance_grpc_service_config.json
- spanner_admin_database_grpc_service_config.json
如要進一步瞭解 gRPC 截止期限,請參閱「gRPC 和截止期限」。
如何調查及解決常見的逾時錯誤
您可能會在下列問題類型中遇到 DEADLINE_EXCEEDED
錯誤:
資料存取 API 問題
為避免資料存取 API 問題,您必須針對特定工作負載適當設定 Spanner 執行個體。下列各節將說明如何調查及解決各種資料存取 API 問題。
檢查 Spanner 執行個體的 CPU 負載
當 CPU 使用率超過建議的健康門檻時,要求延遲時間可能會大幅增加。您可以在 Google Cloud 控制台提供的監控主控台中查看 Spanner CPU 使用率。您也可以根據執行個體的 CPU 使用率建立警示。
解決方法
如要瞭解如何降低執行個體的 CPU 使用率,請參閱「降低 CPU 使用率」一文。
查看要求的端對端延遲時間細目
當要求從用戶端傳送至 Spanner 伺服器,並從伺服器傳回時,需要進行幾個網路跳躍:從用戶端程式庫到 Google 前端 (GFE);從 GFE 到 Spanner API 前端;最後從 Spanner API 前端到 Spanner 資料庫。如果在這些階段發生網路問題,您可能會看到逾時錯誤。
您可以擷取各個階段的延遲時間。詳情請參閱「Spanner 要求中的延遲點」。如要找出 Spanner 的延遲發生位置,請參閱「找出 Spanner 的延遲發生位置」。
解決方法
取得延遲時間細目資料後,您可以使用指標診斷延遲時間,瞭解延遲時間發生的原因,並找出解決方案。
Data API 問題
使用 Spanner 的 Data API 時,如果採用某些不理想的用法模式,可能會導致超出期限的錯誤。本節提供檢查這些非最佳使用模式的規範。
檢查耗用大量資源的查詢
如果嘗試執行耗時的查詢,但未在用戶端程式庫中設定的逾時期限內執行,可能會導致逾時錯誤。耗用大量資源的查詢範例包括 (但不限於) 對大型資料表執行完整掃描、跨多個大型資料表執行交叉彙整,或對非關鍵欄執行查詢執行 (也是完整資料表掃描)。
您可以使用查詢統計資料表和交易統計資料表檢查耗用大量資源的查詢。這些表格會顯示執行速度緩慢的查詢和交易相關資訊,例如平均讀取資料列數、平均讀取位元組數、平均掃描資料列數等。此外,您也可以產生查詢執行計畫,進一步檢查查詢的執行方式。
解決方法
如要最佳化查詢,請參閱 SQL 查詢最佳做法指南。您也可以使用透過先前提及的統計資料表和執行作業取得的資料,來改善查詢並變更資料庫的結構定義。這些最佳做法有助於縮短陳述式的執行時間,或許能幫助您排除逾時錯誤。
檢查鎖定爭用
Spanner 交易需要取得鎖定才能提交。以高輸送量執行的應用程式可能會導致交易爭用相同資源,導致取得鎖定項目的等待時間增加,進而影響整體效能。這可能會導致任何讀取或寫入要求的期限超出。
您可以使用鎖定統計資料表,並查看以下網誌文章,找出讀寫交易高延遲的根本原因。在鎖定統計資料表中,您可以找到鎖定等待時間最長的資料列鍵。
這份鎖定衝突疑難排解指南說明如何找出在鎖定衝突中存取涉及的資料欄的交易。您也可以使用交易標記疑難排解指南,找出鎖定衝突涉及哪些交易。
解決方法
請套用這些最佳做法,減少鎖定競爭。此外,請針對純讀取用途使用唯讀交易,以避免與寫入作業發生鎖定衝突。讀寫交易應保留給寫入或混合讀寫工作流程使用。按照這些步驟操作,應可改善交易執行時間的整體延遲情形,並減少逾時錯誤。
檢查未最佳化的結構定義
為 Spanner 資料庫設計最佳資料庫結構定義前,請先考量在資料庫中執行的查詢類型。在執行某些查詢時,不太理想的結構定義可能會導致效能問題。這些效能問題可能會導致要求無法在設定的期限內完成。
解決方法
最理想的結構定義設計取決於資料庫的讀取和寫入作業。無論結構定義的具體情況為何,都應遵循結構定義設計最佳做法和 SQL 最佳做法指南。只要遵循這些指南,就能避免最常見的結構定義設計問題。其他導致效能不佳的根本原因包括:主鍵的選擇、表格版面配置 (請參閱「使用交錯表格加快存取速度」)、結構定義設計 (請參閱「為效能最佳化結構定義」),以及 Spanner 執行個體中設定的節點效能 (請參閱 Spanner 效能總覽)。
檢查是否有熱區
由於 Spanner 是分散式資料庫,因此結構定義設計必須考量如何避免資源使用率不均。舉例來說,建立單調遞增的資料欄會限制 Spanner 可用來平均分配工作負載的分割數量。這些瓶頸可能會導致逾時。此外,您也可以使用 Key Visualizer 排解熱點造成的效能問題。
解決方法
請參閱上一個章節中所述的解決方法,檢查未最佳化的結構定義,這是解決這個問題的第一步。重新設計資料庫結構定義,並使用交錯索引,避免使用可能造成資源使用率不均的索引。如果按照這些步驟操作仍無法緩解問題,請參閱選擇主鍵以避免資源使用率不均的說明文件。最後,請避免採用不理想的流量模式,例如大範圍讀取,這可能會導致系統無法根據負載進行分割。
檢查是否有設定錯誤的逾時時間
用戶端程式庫會為 Spanner 中的所有要求提供合理的逾時預設值。不過,您可能需要根據特定工作負載調整這些預設設定。建議您觀察查詢的費用,並調整截止期限,以便根據特定用途調整。
解決方法
逾時的預設設定適用於大多數用途。使用者可以覆寫這些設定 (請參閱自訂逾時和重試指南),但不建議使用比預設值更積極的逾時值。如果您決定變更逾時時間,請將其設為應用程式願意等待結果的實際時間長度。您可以嘗試設定較長的逾時時間,但請勿將逾時時間設為低於應用程式願意等待的實際時間,否則會導致作業重試次數增加。
Admin API 問題
與資料 API 要求相比,管理員 API 要求的作業成本較高。CreateInstance
、CreateDatabase
或 CreateBackups
等管理員要求可能需要花費數秒才能傳回回應。Spanner 用戶端程式庫會為執行個體和資料庫管理員要求設定 60 分鐘的期限。這可確保伺服器在用戶端重試或失敗前,有時間完成要求。
解決方法
如果您使用 Google Spanner 用戶端程式庫存取管理員 API,請確認用戶端程式庫已更新並使用最新版本。如果您是透過自己建立的用戶端程式庫直接存取 Spanner API,請確保您設定的期限不會比執行個體和資料庫管理員要求的預設設定 (60 分鐘) 更嚴格。
Google Cloud 控制台問題
從 Google Cloud 控制台 Spanner Studio 頁面發出的查詢不得超過五分鐘。如果您建立的查詢需要超過五分鐘才能執行,您會看到下列錯誤訊息:
後端會取消失敗的查詢,並視需要回復交易。
解決方法
您可以參考 SQL 查詢最佳做法指南,重新撰寫查詢。
Dataflow 問題
在 Apache Beam 中,讀取作業的預設逾時設定為 兩小時,提交作業則為 15 秒。與獨立用戶端程式庫的逾時期限相比,這些設定可讓作業時間更長。不過,如果工作項目太大,仍有可能收到逾時和超出期限的錯誤訊息。如有需要,您可以自訂 Apache Beam 提交逾時設定。
解決方法
如果步驟 ReadFromSpanner / Execute
query / Read from Spanner / Read from Partitions
發生逾時錯誤,請查看查詢統計資料表,找出掃描大量資料列的查詢。然後修改這類查詢,嘗試縮短執行時間。
以下例外訊息顯示另一個 Dataflow 逾時錯誤:
exception:
org.apache.beam.sdk.util.UserCodeException:
com.google.cloud.spanner.SpannerException: DEADLINE_EXCEEDED:
io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after
3599.999905380s.
[remote_addr=batch-spanner.googleapis.com/172.217.5.234:443] at
org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)
工作項目過大,因此導致逾時。在上述範例中,下列兩項最佳化建議可能有所助益。首先,如果尚未啟用「隨機播放服務」,請嘗試啟用。其次,您可以嘗試調整資料庫讀取作業中的設定,例如 maxPartitions
和 partitionSizeBytes
。如需更多資訊,請參閱 PartitionOptions
,瞭解如何縮減工作項目大小。如需這方面的範例,請參考這個 Dataflow 範本。
其他期限超過疑難排解資源
如果完成疑難排解步驟後,仍出現 DEADLINE_EXCEEDED
錯誤,請在遇到下列情況時提交支援案件:
- Google Front End 延遲時間高,但 Spanner API 要求延遲時間低
- 高 Spanner API 要求延遲時間,但低查詢延遲時間
您也可以參考下列疑難排解資源: