第一篇:兄弟連區塊鏈培訓教程Go語言區塊鏈共識算法分布式一致性算法Raft
兄弟連Go語言區塊鏈培訓教程區塊鏈共識算法(1)分布式一致性算法Raft
很多人喜歡Go語言,其實是因為Go語言有其獨特的語言屬性在支撐著其在編程語言界的發展,今天兄弟連Go語言+區塊鏈培訓老師給大家介紹一下關于Go語言區塊鏈共識算法(1)分布式一致性算法Raft,下面我們一起來看一下吧。
# 分布式一致性算法Raft
Paxos自1990年提出以后,相當長時間內幾乎已成為分布式一致性算法的代名詞。
但因其難以理解和實現,目前知名實現僅有Chubby、Zookeeper、libpaxos幾種,其中Zookeeper使用的ZAB對Paxos做了大量改進。
為此,2013年斯坦福的Diego Ongaro、John Ousterhout,提出了新的更易理解和實現的一致性算法,即Raft。
Raft和Paxos均只要保證n/2+1節點正常,即可服務。相比Paxos,其優勢即為易于理解和實現。
Raf將算法分解為:選擇領導者、日志復制、安全性等幾個子問題。
它的流程即為:開始時在集群中選舉出Leader負責日志復制的管理,Leader接收來自客戶端的事務請求(日志),并將它們復制給集群中的其他節點,然后通知集群中的其他節點提交日志,Leader負責保證其他節點與它的日志同步。
當Leader宕機時,集群其他節點重新發起選舉,選出的新的Leader。
### 角色
Raft涉及三種角色:
* Leader:即領導者,負責處理來自客戶端的請求,管理日志復制、以及與Follower保持心跳以維持其領導者地位。
* Follower:即追隨者,負責響應來自Leader的日志復制請求,響應來自Candidate的選舉請求。初始時所有節點均為Follower。
* Candidate:即候選者,負責發起選舉投票,Raft啟動后或Leader宕機后,一個節點從Follower轉為Candidate,并發起選舉,選舉成功后,由Candidate轉為Leader。
如下為Raft角色狀態轉換圖:
(1 Raft)
### Term(任期)
在Raft中使用了Term(任期)的概念,一輪選舉即為一個Term(任期),一個Term中僅能產生一個Leader。
Term使用連續遞增的編號表示,初始時所有Follower的Term均為1。
其中某個Follower定時器到期觸發選舉,其狀態轉換為Candidate,此時Term加1變為2,然后開始選舉,有如下幾種可能:
/ 3
*
1、如果當前Term為2的任期內沒有選舉出Leader或出現異常,Term遞增為3,并開始新一輪選舉。
*
2、此輪Term為2的任期內選舉出Leader后,如果Leader宕機,此時其他Follower轉為Candidate,Term遞增,并發起新的選舉。
*
3、如果Leader或Candidate發現自己的Term比其他Follower小時,Leader或Candidate轉為Follower,Term遞增。
*
4、如果Follower發現自己的Term比其他Follower小時,更新Term與其他Follower保持一致。
每次Term遞增都將發生新一輪選舉,在Raft正常運行過程中,所有節點Term均一致。
如果節點不發生故障,一個Term(任期)會一直保持下去,當某節點收到的請求中Term比當前Term小時拒絕請求。
### 選舉
初始時所有節點均為Follower,且定時器時間不同。
某個節點定時器觸發選舉后,Term遞增,該節點由Follower轉換為Candidate,向其他節點發起投票請求(RequestVote RPC)。
有如下幾種可能:
*
1、收到過半數節點(n/2+1)投票,由Candidate轉換為Leader,向其他節點發送心跳以維持領導者地位。
*
2、如果收到其他節點發送的AppendEntries RPC請求,且該節點Term大于當前節點Term,即發現了新的有效領導者,轉換為Follower,否則保持Candidate拒絕該請求。
*
3、選舉超時,Term遞增,重新發起選舉。
每輪Term期間,每個節點均只能投票1次,如果多個Candidate均沒有接收到過半數投票,則每個Candidate Term遞增,重啟定時器并重新發起選舉。
因定時器時間隨機,因此不會多次出現多個Candidate同時發起投票的問題。
### 日志復制
保證節點的一致性,就要保證所有節點都按順序執行相同的操作序列,日志復制目的即為此。
*
1、Leader接收到客戶端事務請求(即日志),先將日志追加到本地Log中,并通過AppendEntries RPC復制給其他Follower。
*
2、Follower接收到日志后,追加到本地Log中,并向Leader發送ACK消息。
*
3、Leader收到過半數Follower的ACK消息后,將日志置為已提交并正式提交日志,通知客戶端,并發送AppendEntries RPC請求通知Follower提交日志。
### 安全性
/ 3
*
1、每個Term期間只能選舉一個Leader。
*
2、Leader不會刪除或覆蓋已有日志條目,只會追加。
*
3、如果相同索引位置的日志條目Term任期號相同,那么認為從頭到這個索引位置均相同。
*
4、如果某個日志條目在某任期內提交,那么這個日志條目必然出現在更大的Term任期號的所有領導中。
*
5、如果Leader在某索引位置的日志條目已提交,那么其他節點相同索引位置不會提交不同的日志條目。
### RequestVote RPC和AppendEntries RPC
Raft中節點通信使用兩種RPC,即RequestVote RPC和AppendEntries RPC:
RequestVote RPC:即請求投票,由Candidate在選舉期間發起。
AppendEntries RPC:即附加條目RPC,由Leader發起,用于日志復制和心跳機制。
### 后記
本文總結的Raft,及之前文章中的Paxos、2PC、3PC均為基于非拜占庭容錯的分布式一致性算法,即除考慮消息的丟失、超時、亂序,但不考慮消息被篡改。
從下個文章起,將總結基于拜占庭容錯的分布式一致性算法,該算法在比特幣、以太坊、及其他區塊鏈產品中廣泛使用。
/ 3
第二篇:兄弟連區塊鏈培訓Go語言爬蟲編寫
兄弟連區塊鏈培訓Go語言爬蟲編寫
兄弟連教育建議,用戶在考慮培訓周期時要切實結合自身目前所掌握的區塊鏈知識的多少、培訓的目的是簡單的認知提升還是借此高薪就業等等。兄弟連Go全棧與區塊鏈培訓課程設置為5個半月共計22周的學習時長,由淺入深進行講解,助力于小白用戶向區塊鏈工程師的轉型。
課程體系設計架構包括了區塊鏈的基礎語言Go語言、區塊鏈后端技術體系、區塊鏈公鏈、區塊鏈分布式應用開發等內容講解,以及到最后的面試指導和項目實戰。課程由清華微軟谷歌名師團隊精心打造,歷時半年時間共同研發而出。
上次用Scala寫了個爬蟲。最近在閑工夫之時,學習Go語言,便用Go移植了那個用Scala寫的爬蟲,代碼如下: package main
import(“fmt”
“io/ioutil”
“net/http”
“regexp”)
var(ptnIndexItem
= regexp.MustCompile(`(.+)`)
ptnContentRough = regexp.MustCompile(`(?s).*
ptnBrTag
= regexp.MustCompile(`
`)
ptnHTMLTag
= regexp.MustCompile(`(?s)?.*?>`)
ptnSpace
= regexp.MustCompile(`(^s+)|()`))
func Get(url string)(content string, statusCode int){
resp, err1 := http.Get(url)
if err1!= nil {
statusCode =-100
return
}
defer resp.Body.Close()
data, err2 := ioutil.ReadAll(resp.Body)
if err2!= nil {
statusCode =-200
return
}
statusCode = resp.StatusCode
content = string(data)
return }
type IndexItem struct {
url
string
title string }
func findIndex(content string)(index []IndexItem, err error){
matches := ptnIndexItem.FindAllStringSubmatch(content, 10000)
index = make([]IndexItem, len(matches))
for i, item := range matches {
index[i] = IndexItem
}
return }
func readContent(url string)(content string){
raw, statusCode := Get(url)
if statusCode!= 200 {
fmt.Print(“Fail to get the raw data from”, url, “n”)
return
}
match := ptnContentRough.FindStringSubmatch(raw)
if match!= nil {
content = match[1]
} else {
return
}
content = ptnBrTag.ReplaceAllString(content, “rn”)
content = ptnHTMLTag.ReplaceAllString(content, “")
content = ptnSpace.ReplaceAllString(content, ”“)
return }
func main(){
fmt.Println(`Get index...`)
s, statusCode := Get
if statusCode!= 200 {
return
}
index, _ := findIndex(s)
fmt.Println(`Get contents and write to file...`)
for _, item := range index {
fmt.Printf(”Get content %s from %s and write to file.n“, item.title, item.url)
fileName := fmt.Sprintf(”%s.txt“, item.title)
content := readContent(item.url)
ioutil.WriteFile(fileName, []byte(content), 0644)
fmt.Printf(”Finish writing to %s.n", fileName)
} }
代碼行數比Scala版的有一定增加,主要原因有以下幾方面原因: golang 重視代碼書寫規范,或者說代碼格式,很多地方寫法比較固定,甚至比較麻煩。比如就算是if判斷為真后的執行語句只有一句話,按照代碼規范,也要寫出帶大括號的三行,而在Scala和很多其他語言中,一行就行; golang 的strings包和regexp包提供的方法并不特別好用,特別是和Scala相比,使用起來感覺Scala的正則和字符串處理要舒服的多; scala版的爬蟲里面用到了Scala標準庫中的實用類和方法,它們雖然不是語法組成,但用起來感覺像是語法糖,這里很多方法和函數式編程有關,golang的函數式編程還沒有去仔細學習。
當然golang版的爬蟲也有一個優勢,就是編譯速度很快,執行速度在現在的寫法里面體現不出優勢;golang的特性goroutine在這里沒有用到,這段代碼今后會不斷改進。
第三篇:區塊鏈中五種常見共識算法 你知道幾個?
區塊鏈中五種常見共識算法 你知道幾個?
區塊鏈是一種去中心化的分布式賬本系統,可以用于登記和發行數字化資產、產權憑證、積分等,并以點對點的方式進行轉賬、支付和交易。區塊鏈系統與傳統中心化系統相比,具有公開透明、不可篡改、防止多重支付等優點,并且不依賴于任何的可信第三方。
由于點對點網絡下存在較高的網絡延遲,各個節點所觀察到的事務先后順序不可能完全一致。因此,區塊鏈系統需要設計一種機制對在差不多時間內發生的事務的先后順序進行共識。這種對一個時間窗口內的事務的先后順序達成共識的算法被稱為“共識機制”。
在區塊鏈這樣的分布式賬本系統中,保障整個系統的安全性和適應性十分重要,這也是共識算法出現的根本原因。那么,區塊鏈中常見的共識算法都有哪些呢?
1、POW:Proof of Work,工作量證明
POW是比特幣在Block的生成過程中使用的一種共識算法,也可以說是最原始的區塊鏈共識算法了。POW工作量證明,簡單地理解就是,通過一份證明來確認做過一定量的工作。
在比特幣系統中,得到合理的Block Hash需要經過大量嘗試計算。當某個節點提供出一個合理的Block Hash值,說明該節點確實經過了大量的嘗試計算。
這種工作量證明的形式,在我們日常生活中也十分常見。比如駕照,能拿到駕照,說明你已經進行過為期幾個月甚至幾年的練車和考試;再比如現在很火的吃雞和王者榮耀游戲中的K/D(Kill/Death)和勝率,分值越高證明你越厲害,同時也說明你進行了大量的游戲練習和技巧學習。
2、POS:Proof of Stake,權益證明
由于POW機制存在消耗算力巨大、交易確認時間較長,挖礦活動集中容易形成中心化等缺點,便演進出了POS權益證明。POS簡單來說,就是一個根據持有數字貨幣數量和時間來分配相應利息的制度,類似平時我們在銀行中存款。
基于權益證明共識的區塊鏈系統中,參與者的角色是驗證者Validator,只需要投資系統的數字貨幣并在特定時間內驗證自己是否為下一區塊創造者,即可完成下一區塊的創建。下一區塊創造者是以某種確定的方式來選擇,驗證者被選中為下一區塊創造者的概率與其所擁有的系統中數字貨幣的數量成正比例,即擁有300個幣的驗證者被選中的概率是擁有100個幣驗證者的3倍。
在POS模式下,有一個名詞叫幣齡,每個幣每天產生1幣齡。比如你持有100個幣,總共持有了30天,那么,此時你的幣齡就為3000。這個時候,如果你驗證了一個POS區塊,你的幣齡就會被清空為0,同時從區塊中獲得相對應的數字貨幣利息。這下就很有意思了,持幣有利息。并且由于POS是在一個有限的空間里完成,不是像POW那樣在無限空間里尋找,因此無需大量能源消耗。
3、DPOS:Delegated Proof of Stake,授權權益證明
DPOS最早出現在比特股中,又稱受托人機制,它的原理是讓每一個持有比特股的人進行投票,由此產生101位代表。我們可以將其理解為101個超級節點或者礦池,而這101個超級節點彼此的權利完全相等。
從某種角度來看,DPOS有點像是議會制度或人民代表大會制度。如果代表不能履行他們的職責(當輪到他們時,沒能生成區塊),他們會被除名,網絡會選出新的超級節點來取代他們。DPOS的出現最主要還是因為礦機的產生,大量的算力在不了解也不關心數字貨幣的人身上,類似演唱會的黃牛,大量囤票而絲毫不關心演唱會的內容。DPOS通過其選擇區塊生產者和驗證節點質量的算法確保了安全性,同時消除了交易需要等待一定數量區塊被非信任節點驗證的時間消耗。通過減少確認的要求,DPOS算法大大提高了交易的速度。通過信任少量的誠信節點,可以去除區塊簽名過程中不必要的步驟。
4、PBFT:Practical Byzantine FaultTolerance,實用拜占庭容錯 PBFT意為實用拜占庭容錯算法,該算法由Miguel Castro(卡斯特羅)和Barbara Liskov(利斯科夫)在1999年提出來,解決了原始拜占庭容錯算法效率不高的問題,將算法復雜度由指數級降低到多項式級,使得拜占庭容錯算法在實際系統應用中變得可行。
PBFT是一種狀態機副本復制算法,即服務作為狀態機進行建模,狀態機在分布式系統的不同節點進行副本復制。每個狀態機的副本都保存了服務的狀態,同時也實現了服務的操作。
將所有的副本組成的集合使用大寫字母R表示,使用0到|R|-1的整數表示每一個副本。為了描述方便,假設|R|=3f+1,這里f是有可能失效的副本的最大個數。盡管可以存在多于3f+1個副本,但是額外的副本除了降低性能之外不能提高可靠性。
5、RAFT,一致性共識算法
RAFT算法包含三種角色,分別是:跟隨者(follower),候選人(candidate)和領導者(leader)。集群中的一個節點在某一時刻只能是這三種狀態的其中一種,這三種角色可以隨著時間和條件的變化而互相轉換。RAFT算法主要有兩個過程:一個過程是領導者選舉,另一個過程是日志復制,其中日志復制過程會分記錄日志和提交數據兩個階段。RAFT算法支持最大的容錯故障節點是(N-1)/2,其中N為集群中總的節點數量。
國外有一個動畫介紹RAFT算法介紹的很透徹,有興趣的朋友可以結合動畫更好的理解下RAFT算法,這里不再做過多介紹。動畫鏈接地址:thesecretlivesofdata.com
http://
/raft/上述是目前主要的區塊鏈共識算法,當然還有其他算法,比如POET:Proof of Elapsed Time流逝時間量證明,Ripple Consensus瑞波共識機制等。
每種算法,各有千秋,在特定環境下和時間段上被采用都有各自的考慮和意義。對不同的區塊鏈應用場景而言,適合的算法即為最好的算法。


文檔為doc格式
聲明:本文內容由互聯網用戶自發貢獻自行上傳,本網站不擁有所有權,未作人工編輯處理,也不承擔相關法律責任。如果您發現有涉嫌版權的內容,歡迎發送郵件至:645879355@qq.com 進行舉報,并提供相關證據,工作人員會在5個工作日內聯系你,一經查實,本站將立刻刪除涉嫌侵權內容。