建模的重要性:使用精確形式語言發現Paxos實現中的一個錯誤 - brooker
在過去的幾周裡,我一直在學習優秀的P 程式語言,一種用於建模和指定分散式系統的語言。我在 P 中做的第一件事就是實現 Paxos——一種我很熟悉的演算法,有很多微妙的失敗模式,而且很容易出錯。
為了測試 P 的模型檢查器,我特意按照Paxos Made Simple 中的描述實現了一個有缺陷的 Paxos 版本,模型檢查器發現Paxos實現出現錯誤。
我向一位同事提到了這一點,他說他們從未聽說過這個錯誤。我認為它應該更廣為人知,所以我想我應該寫下來:
問題不在於Paxos演算法本身,而在於論文中的描述。Michael Deardeuff 向我指出了這個錯誤,並將它寫在可能是有史以來最好的 Stack Overflow問答中 。
事實證明這是因為 Paxos Made Simple 的文字中有兩個歧義。首先,關於接受(第二)階段的接受者的選擇(來自 Paxos Made Simple):
如果提議者從大多數接受者那裡收到對其準備請求(編號為 n)的響應,那麼它會向這些接受者中的每一個傳送接受請求,以獲得編號為 n 且值為 v 的提議,其中 v 是最高的值 -在響應中編號的提案,或者如果響應沒有報告提案,則為任何值。
如果您按照本宣告的內容,將接受訊息傳送給響應您的第一階段訊息的接受者,那麼問題就不會發生。不幸的是,這也使得演算法在實踐中不太穩健。幸運的是,還有另一種可能的修復方法。再次,來自Michael的回答:
通過接受一個值,該節點還承諾不接受較早的值。
Lamport 在 Paxos Made Simple 中沒有這麼說。相反,他說:
如果接受者收到對編號為 n 的提案的接受請求,則它接受該提案,除非它已經響應了編號大於 n 的準備請求。
Leslie Lamport 是我的技術寫作英雄之一。我重讀了他的一些論文,比如時間邏輯有什麼好處?有時只是因為我喜歡它們的書寫方式。指出這種歧義並不是批評他的寫作,而是提醒您即使在文字中對相對簡單的分散式協議進行清晰的描述也是多麼困難。正如蘭波特本人所說:
散文不是精確描述演算法的方式。
這就是為什麼我如此喜歡 P 和 TLA+ 等語言的重要原因。它們不僅是指定、檢查和建模演算法的好方法,而且還是傳達它們的好方法。如果您使用分散式演算法,我強烈建議您選擇其中一種語言。
相關文章
- 建模重要性:使用建模工具發現Paxos實現中的一個錯誤 - brooker
- Go語言的100個錯誤使用場景(61-68)|併發實踐Go
- 【譯】Chars2vec:基於字元實現的可用於處理現實世界中包含拼寫錯誤和俚語的語言模型字元模型
- 如何實現一個能精確同步滾動的Markdown編輯器
- C語言實現一個簡易的Hash table(7)C語言
- 高階語言實現的幾個點
- Go語言的100個錯誤使用場景(55-60)|併發基礎Go
- 易語言實現一個登入程式
- C語言實現將一個陣列中的奇偶數分別存放C語言陣列
- 今天發現了自己的一個一直都錯誤的觀點
- c語言 - 模仿qsort的功能實現一個通用的氣泡排序C語言排序
- C語言實現的一個簡單的猜數小遊戲C語言遊戲
- 前端另一種多語言的實現思路前端
- [BUG反饋]1.1版本錯誤,新建模型,無法使用,出現SQLSTATE[23000]:錯誤模型SQL
- Golang | Go語言多型的實現與interface使用Golang多型
- 如何使用 JavaScript 實現一門程式語言(1) : 前言JavaScript
- DG使用中遇到的幾個錯誤
- 用自己的程式語言實現了一個網站(增強版)網站
- 今天在github上發現一個go語言初學的文件GithubGo
- 使用Go語言實現一個超級mini的訊息佇列,我是這樣做的Go佇列
- C語言-字串函式的實現(一)之strlenC語言字串函式
- Go語言筆記[實現一個Web框架實戰]——EzWeb框架(一)Go筆記Web框架
- 使用 R 語言實現簡單的文字識別程式
- 使用 Go 語言實現簡單的文字識別(OCR)Go
- 使用GO實現Paxos分散式一致性協議Go分散式協議
- 以DevExpress開發的WinFrom程式的多語言功能的實現devExpress
- Go語言map的底層實現Go
- Go語言實現的Java Stream APIGoJavaAPI
- 以$t形式使用flutter多語言Flutter
- [譯]用javascript實現一門程式語言-語言構想JavaScript
- 如何正確實現 Java 中的 HashCodeJava
- 自己實現一個Controller——精簡型Controller
- 使用 sudo 命令出現錯誤
- go語言使用切片實現線性表Go
- 使用 Rust 語言編寫 Java JNI 實現RustJava
- 使用Rust語言實現帕斯卡三角Rust
- [譯] 簡短而又完全精確的程式語言歷史
- 使用JWT做RESTful API的身份驗證-Go語言實現JWTRESTAPIGo