本頁面將概略說明 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 問題
您必須為特定工作負載適當設定 Spanner 執行個體,才能避免資料存取 API 問題。下列各節說明如何調查及解決不同的資料存取 API 問題。
檢查 Spanner 執行個體的 CPU 負載
CPU 使用率超過建議的正常門檻時,要求延遲時間可能會大幅增加。您可以在 Google Cloud 控制台提供的監控控制台中,查看 Spanner CPU 使用率。您也可以根據執行個體的 CPU 使用率建立快訊。
解決方法
如要瞭解如何降低執行個體的 CPU 使用率,請參閱降低 CPU 使用率。
查看要求的端對端延遲細目
要求從用戶端傳送至 Spanner 伺服器,再傳回用戶端時,需要經過多個網路躍點:從用戶端程式庫到 Google Front End (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 問題
與 Data API 要求相比,Admin API 要求屬於高成本作業。
CreateInstance
、CreateDatabase
或 CreateBackups
等管理員要求可能需要數秒才能傳回回應。Spanner 用戶端程式庫會為執行個體和資料庫管理員要求設定 60 分鐘的期限。這是為了確保伺服器有機會完成要求,避免用戶端重試或失敗。
解決方法
如果您使用 Google Spanner 用戶端程式庫存取管理員 API,請務必更新用戶端程式庫,並使用最新版本。如果您是透過自行建立的用戶端程式庫直接存取 Spanner API,請確保您為執行個體和資料庫管理員要求設定的期限,不會比預設設定 (60 分鐘) 更短。
Google Cloud 控制台問題
從 Google Cloud 控制台的 Spanner Studio 頁面發出的查詢不得超過五分鐘。如果您建立的查詢費用高昂,且執行時間超過五分鐘,系統會顯示下列錯誤訊息:
後端會取消失敗的查詢,並視需要回溯交易。
解決方法
您可以按照 SQL 查詢最佳做法指南,重新編寫查詢。
Dataflow 問題
在 Apache Beam 中,讀取作業的預設逾時設定為 2 小時,提交作業則為 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 請求延遲時間較長,但查詢延遲時間較短
你也可以參考下列疑難排解資源: