YJack0000 / github-issue-blog-post

0 stars 0 forks source link

錯誤重傳機制:Exponential Backoff with Jitter #43

Open YJack0000 opened 5 months ago

YJack0000 commented 5 months ago

這篇文章介紹了分散式系統中如何處理錯誤,並且探討了錯誤重傳策略,如:指數退避(Exponential Backoff)和震盪(Jitter)。

YJack0000 commented 5 months ago

錯誤重傳機制:Exponential Backoff with Jitter

前言

前陣子和朋友們參加分散式系統黑客松。在比賽過程中學到了一些 Choas Engineering 要注意到的東西,所以來記錄一下。

目標問題

在分散式系統中,錯誤是無法避免的。如:服務 A 需要與服務 B 交換資料時,服務 B 掛了。這可能倒置使用者等很久,或是全部的請求都卡在緩衝區(Buffer)中。因此,我們需要設計可容受和減少失敗機率的系統,並避免讓原本低比例的失敗成為全面性中斷故障。

手法

Timeout(超時)

其實在大多數的案例中,超時已經是一個很好的手段了。不論是連線超時或是請求超時將設定一個固定時間的閥值,並將其在超時候放棄掉。

超時設定中最困難的部分是設定一個合理的閥值。如果設定的超時閥值過高,會減損實用性,因為在等待時使用的資源仍在消耗。如果設定的閥值過低,則有兩個風險:

Retires(重試)

Retries are similar to a powerful medicine -- useful in the right dose, but can cause significant damage when used too much.

在少有失敗或為短時間的問題時,重試並不會造成什麼問題。原因是重試請求的總次數少,而且服務端多付出以增加實際可用性的代價也還說得過去。但遇上因為過載(overloading) 或是較長時間的停機時間(downtime)時,會提高負載的重試可能讓事態嚴重惡化。甚至可能在原本的問題解決之後,仍長時間維持高負載,導致復原延遲。

重試策略

然而,當我們在分散式系統中固定時間重試時,它可能會導致所有的服務都在同一時間重試,進而導致系統崩潰。這種現象被稱為“重傳風暴”(reties storm)。那是否有可能將這些重試的時間分開呢?

Backoff(退避)

這次沒有成功就等久一點

退避策略是指在每次重試之後,將等待時間增加一個固定的時間量。但是使用固定的退避時間可能會導致所有節點在相同的時間內重傳,進一步加劇網路雍塞。

Exponential Backoff(指數退避)

指數退避(Exponential Backoff)是常見的退避策略。使每次退避的時間呈指數增加,可以有效的避免在一段時間中的重試互相疊加。然而這個方式可能會導致非常長的退避時間,因為指數函數的成長速度很快。為了避免重試時間過長,實作通常會設定退避的最大值。

Exponential Backoff with Jitter(指數退避結合震盪)

為了更好的避免所有服務在同一時間重試,我們可以使用隨機等待時間,稱為震盪(jitter)。在指數退避中我們可以使用一樣的原理,在選擇等待時間時不只是讓其指數性增加,而是隨機的在一個時間區間內選擇重傳的等候時間。

有幾種常見的 Jitter 方式(實驗結果可以 參考這篇 ):

參考資料

YJack0000 commented 5 months ago

測試留言~~~