1. 程式人生 > >第五章 報警 SLO

第五章 報警 SLO

本章介紹如何在發生重要事件將SLO轉換為可操作的報警。我們的第一本SRE和本書都討論了實施SLO。我們相信,擁有很好的SLO可以衡量你的平臺可靠性,正如你的客戶所經歷的那樣,可以為on-call人員該如何迅速做出響應提供最準確的提示。在這裡,我們提供了有關如何將這些SLO轉換為報警規則的具體指導,以便你在消耗過多的錯誤預算之前響應問題。

我們的示例展示了一系列報警指標和邏輯的複雜實現;討論他們的功能和缺點。雖然我們的示例使用的是簡單的request-driven服務和Prometheus語法,但你可以應用到任何報警框架中。

 

報警注意事項

為了從服務質量指標(SLI)和錯誤預算生成報警,你需要一種方法將這兩個元素組合成一個特定的規則。 你的目標是通知重大事件:消耗大部分錯誤預算的事件。

在評估報警策略時,請考慮以下屬性:

 

精確度

檢測到的事件比例很重要。 如果每個報警對應重大事件,則精度為100%。請注意,報警可能會在低流量時段對非重要事件變得特別敏感(在第86頁的“低流量服務和錯誤預算報警”中討論)。

 

召回率

檢測到重大事件的比例。如果每個重要事件都會發出報警,則召回率為100%。

 

檢測時間

在各種條件下發送報警通知需要多長時間。較長的檢測時間會對錯誤預算產生負面影響。

 

恢復時間

解決問題後報警會持續多長時間。較長的恢復時間可能導致混淆或問題被忽略。

 

重大事件的報警方法

為SLO構建報警規則可能會變得非常複雜。在這裡,我們提出了六種方法來配置重要事件的警報報警,以提高精度,得到一個可以同時控制精度、召回、檢測時間和恢復時間這四個引數選項。以下每種方法都解決了不同的問題,有些方法最終同時解決多個問題。 前三個不可行的方法有助於後三個可行報警策略的應用,方法6是最可行和最強烈推薦的選擇。第一種方法實現簡單但不充分,而最佳方法提供了一個完整的解決方案,可以在長期和短期內保護SLO。

出於本節討論的目的,“錯誤預算”和“錯誤率”適用於所有SLI,而不僅僅是名稱中包含“錯誤”的SLI。在第20頁的“測量內容:使用SLI”一節中,我們建議使用SLI來捕獲正常事件與總事件的比率。錯誤預算給出允許的錯誤事件的數量,錯誤率=錯誤事件/總事件的比率。

 

1:目標錯誤率≥SLO閾值

對於最簡單的解決方案,你可以選擇一個小的時間視窗(例如,10分鐘),並在該視窗內的錯誤率超過SLO閾值時發出報警。

例如,如果SLO在30天內為99.9%,則在前10分鐘的錯誤率≥0.1%時發出警報:

- alert: HighErrorRate

expr: job:slo_errors_per_request:ratio_rate10m{job="myjob"} >= 0.001

這個10分鐘的平均值是用Prometheus的記錄法則計算出來的:

record: job:slo_errors_per_request:ratio_rate10m

expr:sum(rate(slo_errors[10m])) by (job) /sum(rate(slo_requests[10m])) by (job)

如果你不從job中匯出slo_errors和slo_requests,則可以通過重新命名度量值來建立時間序列:

record: slo_errors

expr: http_errors

當最近的錯誤率等於SLO時發出警報意味著系統檢測到以下預算消耗:

告警視窗/SLO期限

圖5-1 顯示了設有10分鐘報警視窗和99.9%SLO示例服務的檢測時間和錯誤率之間的關係。

表5-1 設有10分鐘警報視窗和99.9%SLO的示例服務的檢測時間

表5-1 顯示了即時錯誤率過高時發出警報的優缺點。

優點

檢測時間良好:總停機時間為0.6秒(10*60*0.1%, 10:分鐘;60:秒;0.1%:上文所計算得到的10分鐘的平均值)。

精度很低:警報會觸發許多不會威脅SLO的事件。10分鐘的0.1%錯誤率會發出警報,而每月錯誤預算僅消耗0.02%。

此警報會觸發任何威脅SLO的事件,表現出良好的召回率。

極端情況下,你每天最多可以收到144個報警,即使不需要對此採取任何措施,並且服務仍然符合SLO。

 

2:增加報警視窗

我們可以通過更改報警視窗的大小重新構建前面的示例,以提高精度。 通過增加視窗大小,你可以在觸發報警之前消耗更高的預算。

為了保持報警的數量可控,你決定僅在事件消耗30天錯誤預算的5%(一個36小時的視窗)時才收到通知 :

- alert: HighErrorRate

expr: job:slo_errors_per_request:ratio_rate36h{job="myjob"} > 0.001

現在,檢測時間是:

表5-2 顯示了在較大的時間視窗內錯誤率過高時發出警報的好處和缺點

表5-2 在較大的時間視窗內錯誤率過高時發出警報的優缺點

優點

缺點

檢測時間仍然很好:完全停機需要2分10秒(36*60*0.1%, 36:小時;60:分鐘;0.1%:上文所計算得到的10分鐘的平均值)。

非常差的恢復時間:在100%停機的情況下,警報將在2分鐘後觸發,並在接下來的36小時內持續

比前一個示例更精確:通過確保錯誤率持續更長時間,報警可能會對錯誤預算構成重大威脅。

由於存在大量資料點,因此在較長視窗上計算速率在儲存器或I/O操作方面可能代價較大。

圖5-2顯示,雖然在36小時內,錯誤率已降至可忽略不計的水平,但36小時的平均錯誤率仍高於閾值。

圖5-2 36小時內的錯誤率

 

3:增加警報持續時間

大多數監控系統允許你將持續時間引數新增到報警規則,因此警報不會被觸發,除非該值在一段時間內保持在閾值之上。你可能想要使用此引數作為廉價的方式增加更長的視窗:

- alert: HighErrorRate

expr: job:slo_errors_per_request:ratio_rate1m{job="myjob"} > 0.001

for: 1h

表5-3顯示了使用持續時間引數進行報警的優缺點。

表5-3 使用持續時間引數進行報警的優缺點

優點

缺點

報警可以更高精度。

在觸發之前需要持續的錯誤率意味著警報更可能對應於重大事件。

召回率和檢測時間不佳:由於持續時間不隨事件嚴重程度而變化,因此在100%服務中斷一小時後才會發出警報,0.2%服務中斷也會有相同的檢測時間。100%的中斷將消耗30天預算的140%。

即使度量標準暫時返回到SLO內的級別,持續時間計時器也將重置。 當SLI在滿足於不滿足SLO之間波動時可能永遠不會發出警報。

由於表5-3中列出的原因,我們不建議將持續時間用作基於SLO的報警標準的一部分

圖5-3顯示了在報警觸發前持續10分鐘的服務視窗內5分鐘內的平均錯誤率。每隔10分鐘出現的持續5分鐘的錯誤高峰永遠不會觸發報警,但是總體上看出錯率是35%。

每個峰值消耗了30天預算的近12%,但報警從未觸發。

 

4:關於消耗率的報警

要改進以前的解決方案,你需要建立具有良好檢測時間和高精度的報警規則。為此, 你可以引入消耗速率以減小視窗大小,同時保持警報預算花費不變。

消耗速率是指相對於SLO,服務消耗錯誤預算的速度。 圖5-4顯示了消耗率和錯誤預算之間的關係。

示例服務使用100%消耗率,這意味著它正在消耗錯誤預算,其速率使您在SLO的時間視窗結束時只剩下0的錯誤預(請參閱第一本書中的第4章)。 在30天的時間視窗內SLO為99.9%,持續的0.1%錯誤率正好可以在一個月內消耗完所有錯誤預算:消耗率為100%。

圖5-4. Error budgets relative to burn rates

表5-4顯示了消耗速率,相應的錯誤率以及耗盡SLO預算所需的時間。

通過將警報視窗定為一小時,並設定當消耗掉當月5%的錯誤預算時發出告警,你可以得到用於報警的消耗率。對於基於消耗率的報警,報警觸發所需的時間為:

   ((1 - SLO)/錯誤率)*報警視窗大小*消耗率

警報觸發時消耗的錯誤預算為:

   消耗率*報警視窗大小/SLO期限

1小時的告警視窗消耗掉30天錯誤預算的5%時,錯誤預算的消耗率為36。警報規則現在變為:

   - alert: HighErrorRate

    expr: job:slo_errors_per_request:ratio_rate1h{job="myjob"} > 36 * 0.001

表5-5顯示了基於消耗率的報警的優缺點。

表5-5. 基於消耗率報警的利弊

優點

缺點

良好的精確度:此策略選擇大部分錯誤預算支出以提醒發出報警。更短的時間視窗,計算起來代價較小。 檢測時間好。

更好的恢復時間:58分鐘。

低召回率:35%(與上下文的36相對)的消耗率永遠不會發出警報,但會在20.5小時內消耗掉所有30天的誤差預算。

重置時間:58分鐘仍然太長。

 

5:多次消耗率報警

你的報警邏輯可以使用多個消耗速率和時間視窗,並在消耗速率超過指定閾值時觸發警報。 此選項保留了報警消耗率的好處,並確保你不會忽略較低(但仍然很重要)的錯誤率。

為事件設定工單通知也是一個好主意,這些事件通常會被忽視,但如果不加以控制可能會耗盡你的錯誤預算 - 例如,三天內預算消耗率為10%。 這種錯誤率可以捕獲重大事件,但由於預算消耗率提供了足夠的時間來處理事件,因此你無需緊急通知某人。

我們建議在一小時內將2%的預算消耗和6小時內的5%預算消耗作為緊急通知是合理起始數量,並在三天內將10%預算消耗作為故障工單報警的良好基準。適當的數字取決於服務和基本的報警負載。對於更繁忙的服務,並且根據週末和假日的待命責任oncall, 可能需要六小時視窗的工單提醒。

表5-6顯示了消耗的SLO預算百分比的相應消耗率和時間視窗。

表5-6 建議的時間視窗和消耗率,以消耗SLO預算的百分比

  警報配置可能類似於如下規則:

   expr: (

      job:slo_errors_per_request:ratio_rate1h{job="myjob"} > (14.4*0.001)

      or 

job:slo_errors_per_request:ratio_rate6h{job="myjob"} > (6*0.001)

     )

   severity: page

   expr: job:slo_errors_per_request:ratio_rate3d{job="myjob"} > 0.001

   severity: ticket

圖5-5顯示了根據錯誤率的檢測時間和報警型別。

多個消耗速率允許你根據響應速度調整警報以提供適當的優先順序。如果問題在幾小時或幾天內耗盡錯誤預算,則傳送有效通知是合適的。否則,在下一個工作日處理警報的基於工單的通知更合適。表5-7列出了使用多種消耗率的優缺點。

  表5-7 使用多種消耗率的利弊

優點

缺點

能夠根據關鍵值調整監控配置以適應多種情況:錯誤率高時快速報警;如果錯誤率很低但持續,最終會發出警報。

良好的精度,與所有固定預算的部分報警方法一樣。 因為是三天的時間視窗,所以有很好的召回率。能夠根據人們對防禦SLO的反應速度來選擇最合適的警報型別

更多資料、視窗大小和閾值需要管理和推理。 由於三天的視窗,更長的恢復時間。 如果所有條件均為真,則要避免觸發多個警報,你需要實施報警遮蔽。 例如:5分鐘內10%的預算支出也意味著5%的預算在6小時內消耗完,2%的預算消耗在1小時之內。此方案將觸發三個通知,除非監控系統足夠智慧以防止它這樣做。

 

6:多視窗,多消耗率報警

我們可以在第五節中增強多消耗率報警,以便僅在我們仍在快速消耗預算時通知我們 - 從而減少誤報的數量。 為此,我們需要新增另一個引數:一個較短的視窗,用於檢查在觸發報警時是否仍在消耗錯誤預算。

一個好的指導方案是將短視窗設為長視窗持續時間的1/12,如圖5-6所示。 該圖顯示了警報閾值。 在經歷了10分鐘的15%錯誤之後,短視窗平均值立即超過報警閾值,並且在5分鐘後長視窗平均值超過閾值,此時報警開始觸發。 錯誤停止後5分鐘,短視窗平均值降至閾值以下,此時報警停止觸發。 錯誤停止後60分鐘,長視窗平均值降至閾值以下。

圖 5-6. Short and long windows for alerting

例如,你可以在前一小時和前五分鐘超過14.4倍消耗率時傳送工單級警報。 只有在消耗了2%的預算後,此警報才會觸發, 但顯示出重置時間來停止報警時間設定五分鐘而不是一個小時:

我們建議將表5-8中列出的引數作為基於SLO的報警配置的起點。

表 5-8. Recommended parameters for a 99.9% SLO alerting configuration

我們發現基於了多消耗率的警報是實現基於SLO的警報的有效方式。表5-9顯示了使用多種消耗率和視窗大小的優點和缺點。

表5-9:使用多種消耗率和視窗大小的優點和缺點

優點

缺點

靈活的報警框架,允許你根據事件的嚴重性和組織的要求控制報警型別。

要指定的引數很多,這可能使報警規則難以管理。

良好的精度,與所有固定預算的部分報警方法一樣。

有關管理報警規則的更多資訊,請參閱第89頁的“按比例報警”。

不錯的召回率,因為有三天的視窗。

 

低流量服務和錯誤預算報警

當出現問題需要提供有意義的資訊且請求率較高時,詳細說明的多視窗、多點消耗方法很有效。但是,這些方法可能會導致接收請求率較低的系統出現問題。如果系統具有較少的使用者數或自然的低流量時段(例如夜晚和週末),則可能需要更改你的方法。

在低流量服務中自動區分不重要事件更加困難。 例如,如果系統每小時收到10個請求,則單個失敗的請求會導致每小時錯誤率為10%。 對於99.9%的SLO,此請求構成1,000x消耗率並立即發出警報,因為它消耗了30天誤差預算的13.9%。 此方案在30天內僅允許七個失敗的請求。 單個請求可能會因大量短暫且令人厭倦的原因而失敗,這些原因與大型系統中斷一樣,不一定能用成本效益的方式解決。

最佳解決方案取決於服務的性質:單個請求失敗的影響是什麼? 如果失敗的請求是一次性的、高價值的、沒有重試的請求,那麼高可用性目標可能是合適的。從業務角度來看,調查每個失敗的請求都是有意義的。但是,在這種情況下,警報系統會延遲通知錯誤。我們建議使用幾個關鍵選項來處理低流量服務:

  • 人工生成流量以補償來自真實使用者的訊號不足。

  • 將較小的服務組合成更大的服務以用於監控目的。

  • 修改產品,以便:

    • 需要更多請求才能將單個事件限定為失敗。

    • 單一故障的影響較小。

 

人工生成流量

系統可以模擬使用者活動以檢查潛在錯誤和高延遲請求。在沒有真實使用者的情況下,你的監控系統可以檢測到模擬錯誤和請求,因此你的值班工程師可以在影響太多實際使用者之前對問題做出響應。

人工流量提供更多訊號,並允許你重用現有的監控邏輯和SLO值。你甚至可能已經擁有大部分必要的流量生成元件,例如黑盒探測器和整合測試。

生成人工負載確實有一些缺點。大多數需要SRE支援的服務都很複雜,而且系統控制面很大。理想情況下,系統應進行設計和更改,以便使用人工流量進行監控。 即使是非常重要的服務,你也只能合成使用者請求型別總數的一小部分。 對於有狀態的服務,更多的狀態會加劇這個問題。

此外,如果問題影響真實使用者但不影響人工流量,則成功的人工請求會隱藏真實的使用者訊號,因此你不會收到使用者看到的錯誤通知。

 

合併服務

如果多個低流量服務對一個整體功能有貢獻,則將它們的請求組合到單個更高級別的組中可以更精確地檢測重要事件並且具有更少的誤報。 要使這種方法起作用,服務必須以某種方式相關聯 ——你可以組合構成同一產品的一部分的微服務,或者由同一個二進位制檔案處理的多個請求型別。

組合服務的缺點是單個服務的完全失敗可能不算是重大事件。 通過選擇具有共享故障域的服務(例如公共後端資料庫),可以增加故障影響整個組的可能性。 你仍然可以使用較長時間的警報,最終可以100%捕獲單個服務故障。

 

進行服務和基礎設施更改

對重大事件發出報警旨在提供足夠的通知,以便在耗盡整個錯誤預算之前緩解問題。 如果你無法將監控調整為對短暫事件不太敏感,並且生成人工流量不切實際,則可以考慮更改服務以減少單個失敗請求對使用者的影響。 例如,你可能:

  • 修改客戶端以使用指數退避和抖動進行重試。

  • 設定捕獲最終執行請求的回退路徑,這可以在伺服器或客戶端上進行。

這些更改對於高流量系統非常有用,但對於低流量系統更是如此:它們允許在錯誤預算中有更多的失敗事件,更多的普通訊號,以及更多的時間在事件變得重要之前對其做出反應。

 

降低SLO或增加視窗

你可能還想重新考慮單個故障對錯誤預算的影響是否準確反映了其對使用者的影響。 如果少量錯誤導致你丟失錯誤預算,你是否真的需要尋找工程師來立即解決問題? 如果沒有,使用者會對較低的SLO同樣滿意。 通過較低的SLO,工程師只會收到更大的持續中斷報警通知。

一旦你與服務的利益相關者協商降低SLO(例如,將SLO從99.9%降低到99%),實施更改非常簡單:如果你已經有系統用於報告,監控和警報,則基於 SLO閾值,只需將新SLO值新增到相關係統即可。

降低SLO確實有缺點:它涉及產品決策。 更改SLO會影響系統的其他方面,例如對系統行為的期望以及何時制定錯誤預算策略。 這些其他要求對於產品而言可能比避免一些低訊號報警更重要。以類似的方式,增加用於報警邏輯的時間視窗確保觸發頁面的報警更加重要並且值得關注。在實踐中,我們使用以下方法的某種組合來警告低流量服務:

  • 在這樣做時產生虛假流量是可能的並且可以實現良好的覆蓋

  • 修改客戶端,以便短暫的故障不太可能導致使用者影響

  • 聚合共享某種故障模式的較小服務

  • 設定SLO閾值與失敗請求的實際影響相對應

 

極端可用性目標

具有極低或極高可用性目標的服務可能需要特別考慮。 例如,考慮具有90%可用性目標的服務。 表5-8表示了當在一個小時內消耗了2%的錯誤預算時的報警。因為100%的宕機只會在那個小時消耗掉1.4%的預算,所以這個警報永遠不會觸發。如果你的錯誤預算是在很長一段時間內設定的,那麼你可能需要調整報警引數。

對於具有極高可用性目標的服務,100%中斷的耗盡時間非常短。 對於每月目標可用性為99.999%的服務,100%的中斷將在26秒內耗盡其預算——這比許多監控服務的採集週期小很多,更不用說生成報警時通過電子郵件和簡訊等通知系統傳遞它的目的端時間了。 即使報警直接傳送到自動解決方案系統,問題也可能完全消耗錯誤預算,然後才能得到緩解它。

收到通知說你只剩下26秒的預算並不一定是一個壞策略;這對於保護SLO是沒有用的。 防禦這種可靠性的唯一方法是設計系統,使100%中斷的可能性極低。 這樣,你可以在消耗預算之前解決問題。 例如,如果你最初將此更改推廣到僅有1%的使用者,並以1%的相同速率消耗錯誤預算,那麼現在你要43分鐘才能耗盡錯誤預算。 有關設計此類系統的策略,請參閱第16章。

 

大規模報警

在擴充套件服務時,請確保報警同樣可擴充套件。 你可能想為各個服務指定自定義報警引數。 如果你的服務包含100個微服務(或等效地,具有100種不同請求型別的單個服務),這種情況很快就會積累起無法衡量的工作和認知負載。

在這種情況下,我們強烈建議不要為每項服務單獨指定報警視窗和消耗率引數,因為這樣做很快就會變得勢不可擋。確定報警引數後,將它們應用於所有服務。

管理大量SLO的一種技術是將請求型別分組到大致類似的可用性要求的桶中。 例如,對於具有可用性和延遲SLO的服務,可以將其請求型別分組到以下儲存桶中:

CRITICAL:對於最重要的請求型別,例如使用者登入服務時的請求。

HIGH_FAST:適用於具有高可用性和低延遲要求的請求。 這些請求涉及核心互動功能,例如當用戶點選按鈕以檢視他們的廣告庫存本月賺了多少錢。

HIGH_SLOW:對於重要但對延遲不太敏感的功能,比如使用者單擊按鈕生成過去幾年所有廣告活動的報告,並且不希望資料立即返回。

LOW:對於必須具有某些可用性但是對於使用者來說幾乎不可見的中斷的請求 —— 例如,輪詢處理程式以檢視可能長時間失敗而不會對使用者產生影響的帳戶通知。

NO_SLO:對於使用者完全不可見的功能 ——例如,暗啟動或顯式位於任何SLO之外的alpha功能。

通過對請求進行分組而不是在所有請求型別上放置唯一可用性和延遲目標,可以將請求分組到五個儲存桶中,如表5-10中的示例所示。

表5-10 根據類似的可用性要求和閾值請求類桶

Request class

Availability

Latency @ 90%

[email protected]%

CRITICAL

99.99%

100 ms

200 ms

HIGH_FAST

99.9%

100 ms

200 ms

HIGH_SLOW

99.9%

1,000 ms

5,000 ms

LOW

99%

None

None

NO_SLO

None

None

None

這些儲存桶提供了足夠的保真度來保護使用者的滿意度,但與一個更復雜、管理成本更高的系統相比,它的工作量更小,而且可能更精確地反映使用者體驗。

 

結論

如果你設定的SLOs是有意義的、可理解的,並且可度量,那麼你可以配置報警,只有在錯誤預算中存在可操作的、特定的威脅時才通知值班人員。

用於警告重大事件的技術包括從錯誤率高於SLO閾值時發出警報,到使用多級消耗率和視窗大小。 在大多數情況下,我們認為多視窗、多消耗率警報技術是保護應用程式SLO的最佳方法。

我們希望我們提供了為你自己的應用程式和組織做出正確配置決策時所需的環境和工具。