管理資源調度風險

總覽

Google 的基礎架構採用可大幅度彈性調整運作的設計:即使流量需求遽增,大部分層級還是可以因應調整。這要歸功於調整式層級的核心設計模式,這種基礎架構元件可根據流量模式,動態地重新分配負載。不過,這類調整作業需要時間。由於使用 Cloud Tasks 可分派非常龐大的流量,因此如果流量增加速度快過基礎架構能應付的速度,就會為實際工作環境帶來風險。

總覽

本文提供在高流量佇列中維持高 Cloud Tasks 效能的最佳做法指南。所謂的高 TPS 佇列是指,透過建立或分派的「每秒工作數」(TPS) 佇列,至少達到 500 個。高 TPS 佇列群組則是指一組連續的佇列 (例如 [queue0001、queue0002、…、queue0099]),其中總共建立或分派了至少 2000 個工作。如要查看佇列或佇列群組的 TPS 記錄,您可使用 Stackdriver 指標api/request_count (「CreateTask」作業數) 和 queue/task_attempt_count (工作嘗試次數)。高流量的佇列與佇列群組可能會出現兩種不同的失敗情形:

佇列超載是指工作建立或分派到個別佇列或佇列群組的速度,快過佇列基礎架構能調整因應的速度。同樣地,目標超載是指分派工作的速度導致下游目標基礎架構發生流量遽增的情形。無論哪種情形,都建議按照 500/50/5 模式操作:資源調度速度超過 500 TPS 時,每 5 分鐘的流量增幅不得超過 50%。本文將檢視可能出現資料調度風險的各種情境,並提供範例來說明如何套用這個模式。

佇列超載

任何流量遽增的情形都可能造成佇列或佇列群組超載,導致佇列發生下列情形:

  • 工作建立作業延遲時間增加
  • 工作建立作業錯誤率提高
  • 分派速度降低

如要避免這些情況,我們建議您設置相關控管措施,以因應佇列或佇列群組建立或分派速度可能遽增的任何情形。我們建議冷佇列或佇列群組每秒最多處理 500 個作業,然後以每 5 分鐘增幅 50% 的速度增加流量。理論上,這種增幅時程能在 90 分鐘後達到每秒處理 740K 個作業。有許多情況都會發生這個情形。

例如:

  • 推出需要大量使用 Cloud Tasks 的新功能
  • 在佇列間移動流量
  • 在佇列增減後重新平衡流量
  • 執行批次工作來置入大量工作

在這些情況或其他情況下,請按照 500/50/5 的模式操作。

使用 App Engine 流量拆分功能

如果這些工作是由 App Engine 應用程式建立,您可以利用 App Engine 流量拆分功能 (標準/彈性) 應付流量增加的情況。將流量拆分為兩種版本 (標準/彈性) 可讓需要速率管理的要求隨時間進行轉移,以維持佇列的良好狀態。舉例來說,假設要將流量轉移到新擴展的佇列群組:[queue0000, queue0199] 是尖峰時段每秒共接收 100,000 個建立作業的高 TPS 佇列序列。

[queue0200, queue0399] 是新佇列序列。在所有流量都已轉移後,序列中的佇列數會加倍,而新的佇列範圍會接收 50% 的序列總流量。

部署會增加佇列數的版本時,請使用流量拆分功能將流量逐步轉移到新的版本,然後再轉移到新的佇列。

  • 首先轉移 1% 的流量到新版。例如 100,000 TPS 的 1% 再 50% 會得出有 500 TPS 轉移到新版。
  • 每 5 分鐘的增幅為傳送到新版流量的 50%,詳細說明請見下表:
自部署開始以來的分鐘數 佔轉移到新版總流量的百分比 佔新佇列總流量的百分比 佔舊佇列總流量的百分比
0 1.0 0.5 99.5
5 1.5 0.75 99.25
10 2.3 1.15 98.85
15 3.4 1.7 98.3
20 5.1 2.55 97.45
25 7.6 3.8 96.2
30 11.4 5.7 94.3
35 17.1 8.55 91.45
40 25.6 12.8 87.2
45 38.4 19.2 80.8
50 57.7 28.85 71.15
55 86.5 43.25 56.75
60 100 50 50

版本導向的流量遽增情形

推出會大幅增加佇列或佇列群組流量的版本時,逐步推行同樣也是順利增加流量的重要機制。逐步推行執行個體,讓初始推行到新佇列的作業不會超過 500 個,且每 5 分鐘的增幅不超過 50%。

新的高 TPS 佇列或佇列群組

新建立的佇列特別容易遭受安全攻擊。舉例來說,[queue0000、queue0001、…、queue0199] 的佇列群組在初始推行階段也跟單佇列同樣敏感。對於這些佇列來說,逐步推行是相當重要的策略。請分階段推行會建立高 TPS 佇列或佇列群組的新服務或更新服務,讓初始負載低於 500 TPS,且每 5 分鐘 (或更長的時間間隔) 的分階段增幅不超過 50%。

新擴展的佇列群組

增加佇列群組的總容量時,例如將 [queue0000-queue0199] 擴展為 [queue0000-queue0399],也請按照 500/50/5 的模式操作。請務必記住,就推行程序而言,新的佇列群組與個別群組並無差別。請將 500/50/5 的模式套用到整個新群組,而非只是群組中的個別佇列。對於這些佇列群組擴展作業而言,逐步推出同樣也是相當重要的策略。如果流量來源為 App Engine,則可使用流量拆分功能 (請參閱版本導向的流量遽增情形)。藉由遷移服務將工作新增到增加的佇列時,請逐步推行執行個體,讓初始推行到新佇列的作業總共不超過 500 個,每 5 分鐘的增幅不超過 50%。

緊急佇列群組擴展

有時您可能會想要擴展現有的佇列群組,例如工作新增到佇列群組的速度,預期會超過群組分派速度等情形。如果新佇列的名稱在依字母順序排序時,平均分散在現有的佇列名稱之間,那麼只要新插入的佇列不超過 50% 且各個佇列的流量低於 500 TPS,流量就可立即傳送到這些佇列。這個方法是前述章節所述的流量拆分逐步推行以外的替代方法。

在佇列結尾附加偶數數字的後置字串可達成這種類型的插入命名作業。舉例來說,如果您有 200 個現有佇列 [queue0000-queue0199],然後想要建立 100 個新佇列,請選擇 [queue0000a, queue0002a, queue0004a, …, queue0198a] 做為新佇列名稱,而非 [queue0200-queue0299]。

如果還要新增佇列,您仍可以採用每 5 分鐘插入不超過 50% 佇列的方法。

大規模/批次工作排入佇列

如需新增幾百萬或幾十億之類的龐大工作量時,可使用雙重插入模式。相對於從單一作業建立工作,請使用插入程式佇列。每個新增到插入程式佇列的工作都會擴散傳遞,並將 100 個工作新增到所要佇列或佇列群組。插入程式佇列可隨時間加快速度,例如從 5 TPS 開始,然後每 5 分鐘增幅 50%。

命名工作

建立新工作時,根據預設,Cloud Tasks 會指派一個不重複的名稱給工作。您可以使用「name」 參數為工作指派自訂名稱。不過這會對效能造成大量負擔,加重延遲情形,且可能會提高命名工作相關的錯誤率。如果工作名稱採循序方式 (例如附有時間戳記),則這些成本還可能會大幅增加。所以,如果您自行指派名稱,建議您在工作名稱中使用分佈均勻的字首,例如內容的雜湊。如要進一步瞭解如何為工作命名,請參閱說明文件

目標超載

如果來自佇列的分派作業短時間劇烈增加,Cloud Tasks 可能會超載您正在使用的其他服務,例如 App Engine、Datastore 以及您的網路用量。如果累積了待處理工作,那麼將這些佇列取消暫停,可能就會產生上述的超載服務情形。如同針對佇列超載所給予的建議,我們同樣也推薦您採取 500/50/5 模式防範這種情況:如果佇列分派速度超過 500 TPS,請增加由佇列觸發的流量,每 5 分鐘增幅不超過 50%。請使用 Stackdriver 指標主動監控增加的流量。Stackdriver 提醒可用於偵測可能的危機狀況。

取消暫停或恢復高 TPS 佇列

取消暫停或重新啟用單個佇列或連續佇列時,佇列會繼續執行分派作業。如果佇列中的工作很多,則剛啟用的佇列進行分派的速度可能就會從 0 TPS 遽增到佇列的完全容量。為了提升處理能力,交錯佇列會使用 Cloud Tasks 的 maxDispatchesPerSecond 恢復或控管佇列分派速率。

大量排定的工作

排定同時分派的大量工作也有可能帶來目標超載的風險。如果您需要同時啟動大量工作,請考慮使用佇列速度控管來逐步提高分派速度,或事先明確轉移目標容量。

增加擴散傳遞

更新透過 Cloud Tasks 執行的服務時,增加遠端呼叫數可能會讓實際工作環境遭受風險。舉例來說,假設高 TPS 佇列中的工作呼叫了處理常式 /task-foo。如果新的版本為處理常式新增了多個昂貴的 Datastore 呼叫,則可能會大幅增加呼叫 /task-foo 的費用。這類版本直接帶來的結果,可能就是 Datastore 流量暴增,然後立即反映在使用者的流量變化上。請採用逐步推行或流量拆分功能來管理流量遽增情形。

重試

進行 Cloud Tasks API 呼叫時,程式碼會在發生失敗時重試。不過,當有大量要求因為伺服器端錯誤而發生失敗時,高比例的重試作業可能會加重佇列的超載情形,導致佇列需要更久時間復原。因此,如果用戶端偵測到有大量要求由於伺服器端發生錯誤而失敗,建議您限制外送流量,例如按照《Site Reliablity Engineering》的「Handling Overload」一章所述,採用適應性節流演算法。Google 的 gRPC 用戶端程式庫可實作這個演算法的變化版本

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Cloud Tasks 說明文件