Pub/Sub 是設計用於提供高度可靠性和可擴充性的非同步訊息傳遞服務。這項服務採用核心 Google 基礎架構元件建立而成,許多 Google 產品十多年來都以這個基礎架構元件為基礎。在這個基礎架構之上,Google 產品 (包括廣告、搜尋與 Gmail) 每秒可傳送 5 億多則訊息,總計 1 TB 以上的資料。本文將說明 Pub/Sub 可靠提供這類規模的關鍵設計功能。
判斷訊息傳遞服務的效能
我們可以從三個方面評估 Pub/Sub 等訊息傳遞服務的效能:擴充性、可用性和延遲時間。這三個因素通常彼此不一致,需要在其中一個因素上做出讓步才能改善其他兩個因素。
「可擴充性」、「可用性」和「延遲」等術語可能代表系統的不同屬性,因此下列各節將說明這些術語在 Pub/Sub 中的定義。
擴充性
可擴充的服務應該能夠處理負載的增加,而不會明顯降低延遲時間或可用性。「負載」可能代表 Pub/Sub 之中各種不同的使用維度:
主題數
發佈者數
訂閱項目數
訂閱者數
訊息數
訊息大小
發佈或讀取訊息的速率 (總處理量)
任何指定訂閱項目的待處理作業大小
可用性
在分散式系統中,問題的類型與嚴重性可能會有很大不同。系統針對不同類型問題的處理成效、能否以使用者注意不到的方式順暢地進行容錯移轉,就成了系統可用性的評估依據。故障可能是因硬體 (如硬碟無法運作或網路連線能力問題) 和軟體造成,也可能是由負載引起。當服務 (或在相同硬體中執行的其他軟體元件,或軟體依附元件) 流量激增導致資源不足時,即會發生由負載引起的故障。建立或部署軟體或設定時的人為疏失也可能會降低可用性。
延遲時間
延遲時間這項因素可讓您從時間層面測量系統的效能。服務通常會想要儘可能地將延遲時間降到最低。就 Pub/Sub 而言,兩項最重要的延遲時間指標如下:
確認已發佈訊息花費的時間。
將已發佈訊息傳送至訂閱者花費的時間。
Pub/Sub 基本架構
本節將說明 Pub/Sub 的設計,讓您瞭解該服務如何在保持可用性的同時,仍能具備擴充性與低延遲時間。系統設計為「可水平擴充」,也就是在主題、訂閱或訊息數增加時,可增加運作中伺服器執行個體的數量加以因應。
Pub/Sub 伺服器會在全球所有 Google Cloud 區域中執行。這可讓服務提供快速的全球資料存取服務,同時讓使用者自行決定訊息的儲存位置。Cloud Pub/Sub 提供全球資料存取權,因此發布者和訂閱者用戶端不會知道連線的伺服器位置,或這些服務如何將資料路由。
Pub/Sub 的負載平衡機制會將發布端流量導向最近的 Google Cloud 資料中心,該資料中心允許儲存資料,如 IAM 與管理控制台的「Resource Location Restriction」部分所定義。也就是說,多個區域中的發布者可能會以低延遲的速度,將訊息發布至單一主題。任何個別訊息都會儲存在單一區域中。不過,主題的訊息可能會儲存在多個區域。當訂閱端用戶端要求發布至此主題的訊息時,會連線至最近的伺服器,該伺服器會匯總從所有發布至主題的訊息收集到的資料,並將資料傳送至用戶端。
Pub/Sub 分為兩個主要部分:資料層會處理發布者和訂閱者之間的訊息傳送作業,而控制層則會處理將發布者和訂閱者指派給資料層中的伺服器。資料層中的伺服器稱為「轉寄站」,而控制層中的伺服器稱為「路由器」。當發佈者與訂閱者連線至指派的轉寄站時,不需要路由器的任何資訊 (只要這些轉寄站保持連線即可)。因此,您可以升級 Pub/Sub 控制層,而不會影響任何已連線並傳送或接收訊息的用戶端。
控制層
Pub/Sub 控制層會將用戶端分派給轉送器,為所有用戶端提供可擴充性、可用性和低延遲時間。針對任何主題或訂閱,所有轉寄站都可為用戶端提供服務。當用戶端連線至 Pub/Sub 時,路由器會根據最短的網路距離 (用於評估兩個點之間連線的延遲時間),決定用戶端應連線至哪些資料中心。在任何指定的資料中心內,路由器都會嘗試將總負載分配至整個可用轉寄站集。執行這項作業時,路由器必須平衡兩個不同的目標:(a) 負載的統一性 (即最好均等載入每個轉寄站);與 (b) 指派作業的穩定性 (即負載變更或可用轉寄站集變更時,受影響的現有指派作業越少越好)。路由器採用 Google 研究團隊開發的一種一致性雜湊演算法,在一致性和統一性間達到可微調的平衡。路由器會向用戶端提供一份清單,依序列出適合連線的目標轉寄站。這份排序清單可能會根據轉寄站可用性與用戶端負載型態而發生變更。
用戶端會依據這份清單連線至其中的一或多個轉寄站。用戶端一般會優先連線至路由器最推薦的轉寄站,但也會考慮過去發生的任何故障情況,例如,如果經過數次嘗試均無法順利連線至距離最近的轉寄站,它可能會決定嘗試連線至不同資料中心的轉寄站。為了讓 Pub/Sub 用戶端不必瞭解這些實作細節,在用戶端和轉送器之間會設有服務 Proxy,代表用戶端執行這項連線最佳化作業。
資料層 - 訊息的生命週期
資料層會接收發佈者的訊息,並將訊息傳送至用戶端。瞭解 Pub/Sub 資料層的最佳方式,或許是觀察訊息的生命週期,從服務收到訊息到訊息不再存在服務的時間點。讓我們來追蹤處理訊息的步驟。為實現本節的目的,我們假設發佈訊息的主題已附加至少一個訂閱項目。一般而言,訊息會經過下列步驟:
發佈者傳送訊息。
將訊息寫入儲存空間。
Pub/Sub 會向發布端傳送確認訊息,表示已收到訊息,並保證會將訊息傳送至所有附加的訂閱項目。
在將訊息寫入儲存空間的同時,Pub/Sub 會將訊息傳送給訂閱者。
訂閱者會向 Pub/Sub 傳送確認訊息,表示已處理訊息。
每個訂閱項目至少有一位訂閱者確認訊息後,Pub/Sub 就會從儲存空間中刪除訊息。
首先,發布端會將主題訊息傳送至 Pub/Sub。Proxy 層會對訊息進行加密並傳送至發佈轉寄站,即發佈者連線的目標轉寄站。為了確保傳送,會將訊息立即寫入儲存空間。轉寄站一開始會將訊息寫入 N 個叢集 (其中 N 為奇數),並在將訊息寫入至少 ⌈N/2⌉ 個叢集時,將訊息視為常駐。訊息持久化後,發布轉寄程式會向發布者回報已收到訊息,此時 Pub/Sub 會保證訊息會傳送至所有已附加的訂閱項目。
在每個叢集內,都會將訊息寫入 M 個獨立磁碟 (其中 M 為奇數),且資料必須位於 ⌈M/2⌉ 個磁碟上,才能視為在該叢集中常駐。至少要將任何發佈的訊息寫入共 ⌈N/2⌉ 個叢集中的 ⌈M/2⌉ 個獨立磁碟才能視為常駐,並最終複製到 N*M 個磁碟。
發佈轉寄站擁有附加至主題之所有訂閱的清單。您有責任保留發佈的訊息,以及說明每個訂閱項目已確認哪些訊息的中繼資料。發佈轉寄站針對特定主題接收及儲存的訊息集,以及對確認訊息的追蹤,統稱為「發佈訊息來源」。根據主題的總處理量需求,單一發佈者可能會將它的訊息傳送至多個發佈轉寄站,並將訊息儲存在多個發佈訊息來源中。相同主題的不同發佈者也可能會將訊息傳送至不同的發佈轉寄站。每則訊息都只會傳送至一個發佈轉寄站。Pub/Sub 會隨著吞吐量變化,動態調整接收特定主題訊息的發布轉寄站數量。
訂閱者可透過連線至訂閱轉寄站 (將訊息從發佈者傳送至訂閱者的轉寄站) 來接收訊息。在提取訂閱者情況下,「連線」是指發出提取要求。在推播訂閱者情況下,「連線」是指已向 Pub/Sub 註冊推播端點。建立訂閱項目即保證會將之後發佈的任何訊息都傳送至該訂閱項目,我們將這稱為同步處理點保證。
每個訂閱轉寄站都需要從擁有主題發佈訊息來源的發佈轉寄站要求訊息。與發佈者相同,訂閱者也可以連線至多個訂閱轉寄站來接收訊息。這樣一來,並非每個訂閱轉發器都需要知道或接收主題的每個發布訊息來源,這也是 Pub/Sub 能橫向擴充的重要特性。根據傳送給訂閱者的訊息傳輸量,Pub/Sub 會根據傳輸量變化,動態調整訂閱轉送器的數量,讓訂閱者接收特定主題的訊息。
訂閱轉寄站會向擁有主題發佈訊息來源的一或多個發佈轉寄站提出要求,要求它們提供需要的訊息。發佈轉寄站會將未確認的訊息傳送至訂閱轉寄站,然後訂閱轉寄站會將訊息轉發給訂閱者。
訂閱者處理訊息後,會將確認訊息傳回給訂閱轉寄者。訂閱轉送器會將此確認訊息轉送給發布轉送器,後者會將確認訊息儲存在發布訊息來源中。在主題的所有訂閱均已確認訊息之後,會以非同步的方式將訊息從發佈訊息來源與儲存空間中刪除。
單一主題和訂閱項目的不同訊息可以透過許多發布者、訂閱者、發布轉寄站和訂閱轉寄站傳送。發布者可以同時向多個轉發器發布,而訂閱者可以連線至多個訂閱轉發器來接收訊息。因此,發布者、訂閱者和轉寄者之間的訊息傳遞流程可能相當複雜。下圖顯示單一主題和訂閱項目的訊息流程,不同顏色代表訊息從發布者傳送至訂閱者的不同路徑:
讓 Pub/Sub 持續運作
為了確保 Pub/Sub 等分散式系統能持續運作,並有效為所有客戶提供服務,我們需要對系統有充分的瞭解和控制權。維護服務是我們網站可靠性工程師 (SRE) 的責任。Pub/Sub 工程師分布在世界各地,提供全年無休的支援服務。
環境
維護 Pub/Sub 等系統的第一步,就是在客戶使用前測試軟體。為實現這項功能,我們提供了三個 Pub/Sub 環境:測試、暫存和正式版。測試和準備不包含任何客戶流量;它們僅包含我們持續運作的測試與監控來協助找出版本的任何問題。這兩個環境會在實際執行之前收到軟體的新版本。測試與準備之間的差異在於,後者完全複製了實際執行環境中現有或即將發佈的內容,其中包括軟體版本與指令列標記。其中前者所啟用的功能,可能正由開發人員進行處理,並規劃在未來發佈。
推出作業
我們會盡量降低推出和測試 Pub/Sub 的程序對服務造成的影響。讓我們來看看新版 Pub/Sub 的一般推出步驟:
確保通過所有單元測試與整合測試。
建立所有伺服器的新版本。
將新伺服器部署至測試與準備環境。
在測試與準備環境中執行伺服器數天時間。
如果沒有已知問題,請將伺服器發佈為 Canary 版,即擁有少量客戶流量的實際執行環境子集。
如果在 Canary 版中未偵測到問題,請在幾天時間內將伺服器逐步推出至更多的實際執行環境中,直到將伺服器發佈到所有位置為止。
由於 Pub/Sub 的設計可抵禦失敗,例如透過控制層和資料層分離,因此客戶可以無縫地推出新版伺服器,且不會影響他們看到的效能。
監控
要讓 Pub/Sub 持續運作,關鍵在於在問題發生前,自動偵測並緩解問題。完成這項工作需要對系統進行嚴密監控。網站穩定性工程團隊 (SRE) 維護一組「服務水準指標」(SLI),即說明系統行為之明確定義指標。指標可能包含「完成 CreateSubscription 要求所需的時間」或「發布要求產生的錯誤率」。這些指標會以各種方式測量。其中有些是轉送器和路由器的專屬內部資料。舉例來說,這些指標會評估將訊息寫入磁碟所需的時間。
所有這些措施有助於定義內部服務等級目標 (SLO),也就是 SLI 的具體目標。例如:「CreateSubscription 要求應在五秒內完成。」SRE 會收到服務等級目標違規的快訊,且必須在五分鐘內處理快訊。
「服務水準協議」(SLA) 會列出 SLO,其中定義我們向使用者保證的效能,以及我們未達保證效能時的後果。請參閱 Pub/Sub 的服務水準協議。
我們維護了一組用戶端,這些用戶端會預期發布及訂閱。這些稱為「探針」。資料層和控制層都有探測器。每個探針都會執行特定動作,就像客戶一樣,並測量操作所需的時間。舉例來說,我們有一個探測器會建立新的訂閱項目、發布訊息,並查看建立訂閱項目和接收訊息所需的時間。如果探測器判定任何測量指標不符合預期,系統就會發出 SRE 警報。
伺服器和 Prober 的指標會在多個內部資訊主頁上匯總,SRE 在診斷潛在問題時,會先查看這些資訊主頁。這些頁面可讓您快速存取整個服務的統計資料和圖表。您也可以依照主題、資料中心或個別工作對它們進行劃分。
Google Cloud Monitoring 會提供服務使用者最感興趣的指標。
控制項
我們提供多項控制選項,協助您調整 Pub/Sub 的效能。其中一些控制方式的設計有助於處理資料中心或機器的服務中斷情形。我們可以對一些或全部主題設定「轉送限制」,即指定可以且/或無法連線至轉寄站集之用戶端集的規則。我們可以使用轉送限制來從無法如預期般運作的個別轉寄站工作或整個資料中心排除流量。
我們擁有的另一項可微調功能是流量控制。這項功能允許我們在防止服務發生超載時,最大化總處理量。流量控制是一種流量成形方式,透過此方式可以隨時間消除負載中非預期的突然激增,以獲得更好的服務穩定性。流量控制可在整個系統中或根據各主題或各訂閱者運作,來限制已轉移或未解決的訊息數或位元組數。在這種情況下,「未解決」表示已傳送至用戶端,但尚未確認。我們透過流程控制和路由限制,可提升 Pub/Sub 的效能,而客戶不必擔心這些低層級細節。
摘要
對於考慮採用代管雲端服務的客戶,Pub/Sub 等服務在擴充性、可用性和延遲時間方面的優勢,可說是價值主張。任何非同步訊息傳遞服務都必須在考慮這些功能的情況下,從頭開始建立。Pub/Sub 團隊擁有超過十年的經驗,可快速且可靠地傳送大量訊息,因此打造並維護的服務能滿足 Google 最基本產品的需求。現在,世界上想傳送訊息的所有外部客戶都可以使用這項服務,而不必擔心他們的訊息傳遞系統是否有能力可以處理目前負載 2 倍、10 倍或 100 倍的負載。
詞彙
詞彙 | 說明 |
---|---|
叢集 | 一般共用相同故障網域 (例如,共用區域網路與共用電源) 的機器邏輯群組。 |
控制層 | Pub/Sub 層,負責將發布者和訂閱者指派給資料層的伺服器。 |
資料層 | 負責在發布端和訂閱端之間移動訊息的 Pub/Sub 層。 |
轉寄站 | 資料層中的伺服器。 |
全球資料存取 | Pub/Sub 發布端和訂閱端用戶端不會知道資料的位置。所有路由和儲存作業均由服務本身執行,且必須符合「位置限制」政策。 |
可水平擴充 | 透過增加服務元件執行個體數來順暢處理更多負載的服務能力。 |
訊息 | 透過 Pub/Sub 傳送的資料。 |
網路距離 | 對兩點之間連線延遲時間的測量。 |
探測器 | 這項工作會做為用戶端運作,並預期在 Pub/Sub 伺服器上執行一或多項動作。 |
發佈訊息來源 | 發佈轉寄站接收及儲存的訊息集,以及所有附加訂閱確認的訊息 ID 集。 |
發布/訂閱 (Pub/Sub) 服務 | 將訊息傳送者與訊息接收者分離的訊息傳遞服務。 |
發布端 | 在指定主題上建立訊息並發送 (發布) 訊息的 Pub/Sub 用戶端。 |
路由器 | 控制層中的伺服器。 |
轉送限制 | 規則清單,表示應該或不應該由路由器傳送至用戶端做為可能連線端點的轉寄站。 |
服務水準協議 (SLA) | SLO 的清單,定義向客戶保證的系統效能並概要說明不符合條件時的後果。 |
服務水準指標 (SLI) | 說明系統行為之明確定義的指標。 |
服務水準目標 (SLO) | 服務水準指標的特定目標。 |
訂閱端 | 接收指定訂閱項目訊息的 Pub/Sub 用戶端。 |
訂閱 | 表示對接收特定主題中的所有訊息感興趣的已命名實體。 |
同步處理點保證 | 訂閱項目建立的時間,所有後續發布的訊息都會傳送給訂閱者。 |
主題 | 一種具名實體,代表訊息來源。 |