摘要:本文將會簡要討論秘猿科技是如何對進行性能優(yōu)化的。在區(qū)塊鏈中,的共識是一個連續(xù)的共識。預(yù)處理在傳統(tǒng)的類共識的區(qū)塊鏈中,共識和交易的處理都是串行的。在共識的過程中,是閑置的。減少不必要的消息。例如,在服務(wù)收到時,需要對其合法性進行驗證。
在前兩期中,秘猿小課堂給大家分享了構(gòu)建高性能區(qū)塊鏈內(nèi)核 CITA 背后的思考。這一期,我們深入研究 CITA 是如何進行性能優(yōu)化,并且將交易處理的性能達到 15000 TPS量級
秘猿科技區(qū)塊鏈小課堂第 6 期
點擊關(guān)注秘猿科技在思否的技術(shù)社區(qū)吧~
在區(qū)塊鏈的設(shè)計中,有一個「不可能三角」的說法,即安全、去中心化、性能,這三者只能取其二。Nervos 是用分層設(shè)計來解決不可能三角問題。在底層 Layer1 里,CKB 就選取安全和去中心化,Layer2 選性能。Layer2 追求把性能做到極致,去中心化和安全由 CKB 來解決。
CITA 作為支持智能合約的區(qū)塊鏈框架,有非常良好的性能表現(xiàn),交易處理的性能可以達到 15000 TPS[1],非常適合作為 Layer2 的高性能區(qū)塊鏈解決方案。本文將會簡要討論秘猿科技是如何對 CITA 進行性能優(yōu)化的。
微服務(wù)架構(gòu)傳統(tǒng)的公有區(qū)塊鏈往往采用整體式架構(gòu)。因為需要考慮去中心化,就需要考慮節(jié)點可以在普通硬件上可以執(zhí)行,而在架構(gòu)設(shè)計上無法兼顧性能。CITA 作為專門面向企業(yè)用戶設(shè)計的高性能許可鏈(許可鏈可以是聯(lián)盟鏈,也可以是公有許可鏈),采用微服務(wù)架構(gòu),可以更好的利用服務(wù)器集群,而不是使用單一機器運行節(jié)點。這樣可以充分利用硬件的優(yōu)勢,節(jié)點不再是一個物理概念,而是一個邏輯概念。
CITA-BFT傳統(tǒng)的 PBFT 類算法中,一般使用三階段協(xié)議 prevote、precommit、commit ,以 Tendermint 為例。
Commit 階段主要是為了 Proposer 向其他節(jié)點再廣播一輪 BlockProof,使得所有節(jié)點統(tǒng)一投票。但是實際上在 Precommit 階段,各個節(jié)點已經(jīng)收集足夠的投票,只是投票集合可能不一致。比如對于 ABCD 四個節(jié)點,A 可能收到 ABCD 的投票,B 只收到 BCD 的投票。由于投票屬于 Block 的一部分,也需要共識,為了保證節(jié)點統(tǒng)一投票,所以由 Proposer 再進行一輪廣播。
在 CITA-BFT 中,我們優(yōu)化了 Commit 階段。在區(qū)塊鏈中,Block 的共識是一個連續(xù)的共識。所以,我們可以將當前 Block 的 Proof 放到下一個塊的 Proposal 中,這樣可以在下一個塊的 Prevote 階段對上一個 Block 的 Proof 進行統(tǒng)一,不再廣播共識后的 Block。
這樣做的優(yōu)點有兩個:
減少了一輪消息的廣播,縮短了共識時間,并且減少了網(wǎng)絡(luò)的負擔。
傳統(tǒng)的 PBFT 類共識算法在 Commit 階段,如果 Proposer 發(fā)送掉線等情況,會需要額外的一輪進行共識,而在 CITA-BFT 則不會發(fā)生這種情況。
在傳統(tǒng)的 PBFT 類共識的區(qū)塊鏈中,共識和交易的處理都是串行的。在共識 Block 的過程中,Executor 是閑置的。共識完成之后,將新的 Block 發(fā)送給 Executor 處理,Consensus 等待 Executor 處理完之后才能進行新的高度的共識,此時 Consensus 模塊是閑置的。待 Executor 處理完 Block 之后,發(fā)送最新的 Status 之后,Consensus 才進行新高度的共識。
在實際的共識過程中,節(jié)點在 Prevote 階段收到 Proposal 并驗證之后,Proposal 就有很大可能變成最終 Commit 的 Block。在網(wǎng)絡(luò)情況正常的情況下,通常一輪共識即可完成當前高度的 Block,此時如果提前對 Proposal 中的交易進行處理,則在共識流程中的后半部分則和交易的執(zhí)行是同時進行的。當 Executor 處理完之后,等待 Consensus 發(fā)送已經(jīng)確認的 Block,此時 Executor 只需要判斷此 Proposal 是否是共識的 Block。如果是,則直接將處理結(jié)果進行 Finalize,并通知 Consensus 進行新高度的共識;如果否,則重新處理,這種情況和沒有預(yù)執(zhí)行的流程是一致的。
這樣在多數(shù)情況下區(qū)塊都能提前處理,將交易處理的時間提前。即便在較壞情況下,進行多輪共識時,Proposal 也可以按照時間戳進行比較,打斷當前正在進行的預(yù)處理,執(zhí)行更新的 Proposal。在最壞情況下,沒有收到 Proposal 或者收到錯誤的 Proposal,Executor 也和原來的共識流程相同,在收到 CommitedBlock 之后,進行交易的處理,并沒有任何性能上的損失。
緩存在性能優(yōu)化中,緩存是一種常見的手段,同樣在 CITA 中也存在大量緩存,來解決性能問題。
簽名驗證緩存。通常交易簽名的驗證比較耗時,對于已經(jīng)驗證通過的交易,根據(jù)其 Hash 將驗證結(jié)果進行緩存。這樣如果節(jié)點再收到同樣的交易(可能是用戶重復(fù)發(fā)送或者從其他節(jié)點轉(zhuǎn)發(fā))時,則可以命中緩存,減少驗證簽名的時間消耗。
區(qū)塊信息緩存。對于在交易處理過程中,或者用戶查詢操作中,經(jīng)常會需要查詢 Block 或者 Transaction 等信息,可以將此類信息緩存,這樣能大大提高查詢的效率。
在交易處理過程中,需要從數(shù)據(jù)庫中讀取之前的 State,而 MPT 的查詢路徑比較長,需要多次 DB 的查詢,非常耗時。在 CITA 中,會將經(jīng)常使用到 Account 進行緩存。
通過緩存技術(shù),大大減少了交易驗證和處理的時間。
在微服務(wù)架構(gòu)中,由于服務(wù)的拆分導(dǎo)致各個微服務(wù)之間消息通信比較頻繁,這樣消息中間件非常容易成為瓶頸。一方面,由于我們使用了微服務(wù)架構(gòu),消息中間件本身可以多帶帶部署,可以通過提高硬件能力進行縱向擴展,也可以通過集群的方式進行橫向擴展。
除此之外,我們還對微服務(wù)之間的消息進行優(yōu)化,來提高微服務(wù)間通信的效率。
消息壓縮。例如在壓力比較大時,Block 中往往有上萬筆交易,這樣消息會非常大。因此我們采用了消息壓縮技術(shù),在消息超過一定大小時,會對其進行壓縮,這樣減少消息中間件的壓力,同時也減少了傳輸量,提高了傳輸速度。
減少不必要的消息。例如,在 Consensus 服務(wù)收到 Proposal 時,需要對其合法性進行驗證。由于其可能包含大量交易,會導(dǎo)致傳輸量很大。因此在 Consensus 可以先驗證交易的 Hash 是否正確,再將 Proposal 的其他信息和交易的 Hash 發(fā)送給 Auth 模塊即可,而不用將整個交易發(fā)送給 Auth 模塊。
打包發(fā)送。將消息打包,也是一種比較常見優(yōu)化手段。比如在 RPC 模塊中,需要將交易發(fā)送給 Auth 模塊進行驗證,在壓力比較大的時候單個消息發(fā)送則消息數(shù)量會非常大,此時 RPC 會將消息進行打包后再發(fā)送給 Auth 模塊,可以大幅度的減少消息的數(shù)量,從而減少消息中間件的負載,提高消息的發(fā)送速度。
在 Bitcoin 中,為了解決輕節(jié)點的交易驗證問題,引入了 MerkleTree。但是 Merkle Tree 的每個節(jié)點的產(chǎn)生都要計算一次 Hash,而 Hash 計算非常耗時。
大家注意到最后的葉子節(jié)點 Hc 是直接復(fù)制了 Hc。這樣是因為 Bitcoin 和 Ethereum 中交易是依次加入到 Merkle Tree 中,可以遞增地去構(gòu)造 Merkle Root。比如節(jié)點當前的 PendingBlock 中有交易 TxA、TxB、TxC、TxD,當前的 Merkle Root 是 H(ABCD)。新交易來 TxE 來了之后,計算 H(EE),再向上計算,這樣原有的 H(ABCD) 部分不用再計算。
當交易 TxF 來了之后,替換掉最右邊的 TxE,再依次向上計算 root,這樣只計算一部分就可以了。之前的 H(ABCD) 部分不用再重新計算。
在 CITA 中,交易會先經(jīng)過 Auth 驗證進入交易池,然后由 Consensus 一次性選取交易打包后共識,最后再由 Executor 處理,同時將處理后的結(jié)果 Receipt Root 存入 header 中 。由于是先共識交易內(nèi)容然后再計算交易的結(jié)果,所以 Block 中的交易的處理結(jié)果 Receipt Root 順序已經(jīng)完全確定,不會再發(fā)生修改了。由此我們可以將所有 Receipts 一次性算出其 Receipt Root,而不用考慮其動態(tài)計算的過程。由此我們可以優(yōu)化 Receipt Root 的計算。
對比 Bitcoin 和 Ethereum 中的 Merkle Tree,會發(fā)現(xiàn)由于沒有奇數(shù)節(jié)點的復(fù)制,節(jié)點 E 這里的 Hash 計算會減少。我們稱這棵樹為 Static Merkle Tree。
另外,在 Ethereum 中每筆交易都會產(chǎn)生新的 State Root,而 State Root 的計算又是非常耗時的。因此在 CITA 設(shè)計之初,交易計算完之后,只會將其狀態(tài)更新到 Account Model 中,而不會將其變更更新到 State 的 MPT 中。只有在整個 Block 計算完成之后,才會將所有的計算結(jié)果提交到 State 的 MPT 中并計算 State Root,這樣大大減少了 MPT 的操作和計算。在 Ethereum 最新的設(shè)計中也采用了同樣的方案。
簽名驗證當前 Bitcoin 和 Ethereum 都采用了 secp256k1 的簽名算法,在交易驗證中,簽名的驗證尤其消耗 CPU 資源并且耗時。CITA 支持多種簽名算法,默認采用 secp256k1。在筆者的電腦(Thinkpad 470p i7-7820HQ)上簡單的轉(zhuǎn)賬交易的簽名驗證速度大約為 3000 多每秒。Auth 模塊提供了交易的并行驗簽,這樣可以充分發(fā)揮硬件的優(yōu)勢,提高系統(tǒng)的驗簽速度。
除此之外,CITA還實現(xiàn)了 Ed25519 簽名,相比 secp256k1 性能更好,并且在安全性方面也更有優(yōu)勢,用戶可以根據(jù)個人需求選擇自己想要的簽名算法。我們性能測試的 15000 TPS 的數(shù)據(jù)指的是 secp256k1。
異步處理在軟件設(shè)計中,異步處理通常也是比較好的性能優(yōu)化手段。除了前文提到的交易預(yù)處理,在 CITA 中的其他模塊中也存在一些這樣的設(shè)計。比如在 Executor 中,Block 執(zhí)行完成之后,需要將最新的 State 保存到 DB,而一旦 State 狀態(tài)變更比較多時,此操作將比較耗時。由此,Executor 提前將 Status 發(fā)送給其他模塊,然后再到 DB 進行存儲。當然可能會在存儲失敗時導(dǎo)致異常情況,因此在 Conseneus 會保存最新的幾個 Block,來防止其他微服務(wù)內(nèi)存儲失敗的特殊情況發(fā)生。
批量交易另外,CITA提供了批量交易的接口,用戶可以組裝多個交易數(shù)據(jù),共享同一個簽名。這樣原來的多個交易就變成一個交易,減少交易存儲和簽名驗證,加快交易的處理,同時也降低了用戶發(fā)送交易的手續(xù)費。例如用戶 A 需要調(diào)用 N 個不同的合約,原來需要發(fā)送 N 筆交易,通過批量交易的方式,可以將合約調(diào)用的 data 按照既定格式拼裝在一起,然后再進行一次簽名發(fā)送到批量交易合約,合約再將 data 解析成多個合約調(diào)用。
當然批量交易只能算作一筆復(fù)雜的組合交易,只完成了一次正常交易的處理流程,因此在性能測試中只能算作一筆交易。CITA 在性能測試中并未采用此手段。
RustCITA 中絕大部分代碼是用 Rust 語言實現(xiàn)。Rust 語言的極小運行時,與 C 語言媲美的優(yōu)異性能,也是 CITA 良好性能的一大保證。作為國內(nèi)最早使用 Rust 的團隊,從 2016 年開始至今也在和 Rust 一同成長。 Rust 語言的其他特性:保證內(nèi)存安全,基于 trait 的泛型,模式匹配,類型推斷,高效 C 綁定等等,也極大的提高了我們的開發(fā)效率。
未來我們還會在微服務(wù)架構(gòu)改進,網(wǎng)絡(luò)層,Block/Transaction 廣播,狀態(tài)存儲,硬件加速,VM,并行計算等等各個方面做更多研究,將 CITA 性能提上一個更高的水平。
參考文獻CITA技術(shù)白皮書:https://github.com/cryptape/c...
Ed25519: https://exonum.com/blog/09-27...
eip-658:https://github.com/ethereum/E...
batch_tx:https://docs.nervos.org/cita/...
Rust versus C gcc fastest programs: https://benchmarksgame-team.p...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/24707.html
摘要:狀態(tài)機模型區(qū)塊鏈用許多的節(jié)點共同模擬了一臺多復(fù)本的狀態(tài)機。區(qū)塊鏈共識的四個階段第一階段是加入共識加入共識階段決定了什么樣的節(jié)點可以參與共識協(xié)議。第四階段是退出共識這是常常被忽略的部分。 在接下來的秘猿科技小課堂里,我們會從技術(shù)角度、經(jīng)濟模型設(shè)計角度、以及共識角度來拆解 Nervos 加密經(jīng)濟網(wǎng)絡(luò)中,底層公鏈 CKB 的設(shè)計理念。而本文將會作為技術(shù)角度核心設(shè)計 Cell 模型的預(yù)備文章,...
摘要:為了能夠讓數(shù)據(jù)情況能夠一目了然,我們開發(fā)了數(shù)據(jù)可視化面板,節(jié)點管理員可以輕松了解節(jié)點的運行健康狀態(tài)。 CITA 是秘猿科技從 2016 年就開始研發(fā),2017 年開源的高性能區(qū)塊鏈內(nèi)核。CITA 作為高性能區(qū)塊鏈內(nèi)核,可以用來開發(fā)各種聯(lián)盟鏈,甚至公有鏈系統(tǒng),具有為穩(wěn)定、高效、靈活、可適應(yīng)未來等特點。為了降低使用門檻,我們還提供了增加 CITA 易用性的工具鏈:包括錢包,緩存服務(wù)器,SD...
摘要:第一類模式是在公鏈項目中運用的最廣泛應(yīng)用的共識算法,比特幣長達年的運行已充分證明的安全性與穩(wěn)定性。此時當前區(qū)塊已是合法區(qū)塊但是未獲得最終確認,類似于比特幣未獲得個塊確認存在回滾的可能性。 showImg(https://segmentfault.com/img/bVbtamO?w=1000&h=600); 共識算法是分布式系統(tǒng)保證節(jié)點數(shù)據(jù)狀態(tài)一致性的方法,在區(qū)塊鏈的共識算法分POW(工...
摘要:維度公有鏈聯(lián)盟鏈私有鏈讓我們換一個維度,按照區(qū)塊鏈的服務(wù)對象來分公有鏈為公眾提供服務(wù)的區(qū)塊鏈。聯(lián)盟鏈私有鏈在具體實施上有不同的許可鏈選項可以是節(jié)點許可鏈出塊許可鏈或者完全許可鏈,由此也會有相應(yīng)的優(yōu)缺點,在此不再重復(fù)。 在我們討論區(qū)塊鏈時,分類是不可避免的一件事情。想必大家都聽說過「公有鏈、聯(lián)盟鏈、私有鏈、許可鏈、無需許可鏈」這些詞匯,雖然我們已經(jīng)耳熟能詳,然而這些名詞并沒有公認的定義。...
摘要:和比特幣網(wǎng)絡(luò)傳輸協(xié)議的一系列優(yōu)化使得比特幣的新區(qū)塊幾乎可以在瞬間被全世界的礦工接收,非常有效的降低了孤塊率,保證了網(wǎng)絡(luò)安全。 這篇文章試圖討論全節(jié)點對于區(qū)塊鏈的意義。 角色 我們都知道,區(qū)塊鏈網(wǎng)絡(luò)中的節(jié)點有不同的角色。例如: 出塊節(jié)點 出塊節(jié)點負責打包交易,生產(chǎn)區(qū)塊。出塊節(jié)點在不同的地方有不同的名字,例如比特幣和以太坊中的礦工/礦池,Bitshares的Delegator,EOS的Pr...
閱讀 2435·2023-04-26 00:46
閱讀 598·2023-04-25 21:36
閱讀 740·2021-11-24 10:19
閱讀 2286·2021-11-23 09:51
閱讀 1031·2021-10-21 09:39
閱讀 846·2021-09-22 10:02
閱讀 1680·2021-09-03 10:29
閱讀 2717·2019-08-30 15:53