小白解釋:什麼是分散式微服務中的冪等? - LispCast

banq發表於2019-04-05

冪等意味著重複無關緊要。這意味著您可以安全地重試操作而不會出現問題。典型的例子是電梯按鈕:你按兩次它就不會叫來兩部電梯。我們在這裡探索為什麼我們希望在電子郵件伺服器中使用該屬性。

什麼是冪等?為什麼它對分散式系統中的程式設計有很大幫​​助?到本集結束時,您將瞭解如何在自己的系統中實現冪等性。
嗨,我的名字是Eric Normand,我透過函數語言程式設計幫助人們茁壯成長。冪等是重要的,因為它捕獲了安全重試的本質。如果沒有安全重試,您實際上無法實現安全的分散式協議。
什麼是冪等?它的本質是,如果你問兩次,它就像問一次一樣。它具有相同的效果。典型的例子是電梯按鈕,你走到電梯口,你按下按鈕。它亮了,其他人來了,他們也按下按鈕,同樣的按鈕,儘管這個按鈕已經被你按亮了。
我們知道後面的人再按是沒有效果的,我們仍然想出於某種原因這樣做。這是一個簡單的案例,也許他們是對的,也許訊號沒有到達電梯,反正值得嘗試,因為它不會傷害任何事情。這就是我們想要在我們的分散式系統中灌輸的東西。從技術上講,它是一個代數屬性。
當你在談論按下按鈕時,這是你在世界上的一種活躍效果。在代數中,它是純函式,數學函式的屬性。這意味著,如果您將字串的字母大寫兩次,則無關緊要。第一次就夠了。從技術上講,如果將F應用於某個值,則假設為F(x),則應用F與應用F(x)相同。
你執行兩次F應用,它與單個應用具有相同的效果,你可以說這意味著重複並不重要。我按了兩次按鈕。第二個並不重要。如果我應用了兩次相同的功能,第二次無關緊要。第一次很重要。第二次,第三次,第五次,那些無所謂。
為什麼這很重要?在分散式系統中,特別是在分散式系統中,我們遇到這樣的問題,即網路上的訊息是不可靠的。基本上,如果您傳送訊息,它可能無法到達那裡,您將不會知道。你不知道它是否到了那裡。
有時,你知道它是否沒有到達那裡。你得到一些連線斷開的訊息,但有時你只是聽不到回覆。它超時了。
它到了那裡,確認超時了,還是從未到過那裡?其他系統崩潰了嗎?它在傳送我的電子郵件之前還是在傳送我的電子郵件之後崩潰了?你不知道。它崩潰了,為時已晚。電子郵件實際上是一個很好的例子,因為您不想傳送兩次相同的電子郵件。
假設您向一個電子郵件伺服器傳送一條訊息:“請將此電子郵件傳送給我的客戶。”但是您沒有收到客戶的回覆,那你做什麼?發生了什麼?你再次傳送一次嗎?
糾結之處在於:如果郵件伺服器已經幫你傳送了電子郵件怎麼辦?同一封電子郵件傳送兩次嗎?如果它沒有傳送它並且我不再次傳送,那麼客戶可能會收不到電子郵件。
這確實是一個真正的商業問題。冪等將解決這個問題。如果我可以再次傳送相同的訊息,並且它不會破壞任何東西,第二次傳送將沒有效果,就像電梯按鈕一樣,我可以整天傳送這條訊息。我可以傳送一百次,但是電子郵件伺服器只會傳送一次,這是好事。

這個電子郵件伺服器所做的就是解耦:它將產生的結果數量與請求該結果的次數進行了分離。我可以請求它一百次,但它只會傳送一次結果數量,這才是你真正想要的東西,您希望能夠使用有限的資訊保安地重試。
接收郵件的伺服器必須記住對方郵件伺服器傳送過的所有電子郵件的ID,這是完全完整的冪等性。通常,那是不切實際的。你不記得每一個ID,因為它可能有數百萬。他們可以追溯到很多年前。您不太可能需要一個花費數年才能送達的請求。
在實際情況中,可能會有一個視窗,上面寫著“好吧,我們會保留三天的ID。”這意味著您可以在這三天內重新傳送相同的ID,伺服器不會再次傳送它。您必須找到一些實際限制,以平衡記憶體要求和您在系統中執行的重試。
請注意,非常重要的是,這種標識ID概念非常重要。如果您沒有標識概念,再次傳送相同的訊息意味著什麼?如果我想向此人傳送兩封電子郵件,我需要能夠向他們傳送兩封電子郵件。我需要某種方式說明這兩份郵件是不同的,如果我想重試,我想要某種方式說明這個與那個是相同的。

您需要一些標識ID證明,如果您正在檢視電梯按鈕,那麼這個電梯服務的電子裝置中可能存在一個特徵,它知道我按下了是哪個按鈕,是三樓或四樓的,這個按鈕有一些識別符號,首先允許它被按亮,並保持點亮狀態,直到需要關閉它時。
這個識別符號可能在多個地方使用,,“哦,我們需要在三樓上升電梯,因為我們知道那個被按的按鈕及其含義。”“嘿,我已經傳送了三樓的電梯,我不需要再這樣做了。“ 電梯系統正在使用識別符號。

你需要一個標識ID,其次一旦你擁有了這個ID,你就會使用一個是冪等操作的資料結構,具有冪等操作的公共冪等資料結構是一個set集合,如記憶體集。
如果您有一個數字集合set,則為每封電子郵件指定一個唯一的數字號碼,當電子郵件伺服器傳送電子郵件時,它會知道電子郵件的數字,會將其新增到這個數字集合中。如果新增兩次也沒有關係,這時你已經有了冪等性。
電梯也是如此,如果你有一個帶有ID的按鈕,這意味著您可以傳送兩次,並且傳送兩次沒有任何效果。

要確定是否已經傳送過它?
非常簡單。
在將事物新增到集合Set中之前,您需要設定“集合是否已經包含此ID?”如果確實如此,那麼您就完成了。如果沒有,則傳送電子郵件,然後將ID放入集合中。還有其他資料結構是冪等的。如果你有雜湊對映,那麼它們是冪等的。
如果您新增相同的鍵和值兩次,那麼它沒有額外的影響。您可以考慮使用冪等的另一件事就是向數字新增零。如果你需要某種冪等的加法,你就可以做到。


總結
讓我們回顧一下。冪等意味著重複無關緊要。它是某些功能,某些操作的代數屬性,但我們將其擴充套件到世界上的行為。我們將它擴充套件到我們可以對世界產生的效果,我們說要求效果兩次與請求一次相同。那些副本也沒關係。
我們在分散式系統中需要它,以便我們可以安全地重試。它允許我們將完成的內容與我們請求它完成的次數分離。您可以使用冪等資料結構和操作輕鬆實現它。它需要只是訊息中的標識ID概念。
尋找那些需要正好發生一次的服務,比如可能就像傳送電子郵件一樣的服務。然後將訊息寫入日誌,將它們包裝在類似於使其具有冪等性的資料結構中就好了。
 

相關文章