輪對的分佈式註冊表:Hyperledger Fabric 的體驗

你好,我在DRD KP項目(用於監控輪對生命週期的分佈式數據註冊中心)團隊工作。 在這裡我想分享一下我們團隊在技術限制下為這個項目開發企業區塊鏈的經驗。 在大多數情況下,我將討論 Hyperledger Fabric,但此處描述的方法可以推斷到任何許可的區塊鏈。 我們研究的最終目標是準備企業區塊鏈解決方案,使最終產品易於使用且維護起來不太困難。

這裡不會有任何發現、意想不到的解決方案,也不會涵蓋任何獨特的發展(因為我沒有它們)。 我只是想分享我卑微的經驗,表明“這是可能的”,也許,在評論中閱讀其他人做出好的和不太好的決定的經驗。

問題:區塊鏈尚不可擴展

如今,許多開發人員的努力旨在使區塊鏈成為一種真正方便的技術,而不是一個漂亮包裝中的定時炸彈。 狀態通道、樂觀匯總、等離子和分片可能會變得司空見慣。 有一天。 或者也許 TON 將再次推遲發布六個月,而下一個 Plasma Group 將不復存在。 我們可以相信另一個路線圖並在晚上閱讀精彩的白皮書,但此時此地我們需要利用我們所擁有的東西做點什麼。 搞定吧。

當前項目中分配給我們團隊的任務大致是這樣的:有很多主體,達到數千人,他們不想建立信任關係; 有必要在DLT的基礎上構建一個可以在普通PC上運行、沒有特殊性能要求的解決方案,並提供不比任何中心化記賬系統差的用戶體驗。 該解決方案背後的技術應該最大限度地減少惡意數據操縱的可能性——這就是區塊鏈出現的原因。

白皮書和媒體的口號向我們承諾,下一步的發展將允許每秒數百萬筆交易。 到底是什麼?

以太坊主網目前的運行速度約為 30 tps。 僅憑這一點,就很難將其視為一種適合企業需求的區塊鏈。 在許可的解決方案中,已知顯示 2000 tps 的基準測試(法定人數) 或 3000 tps (超重織物,出版物中的內容有點少,但請記住,基準測試是在舊的共識引擎上進行的)。 曾是 嘗試從根本上改造 Fabric,它給出的結果並不是最差的,20000 tps,但到目前為止這些還只是等待穩定實施的學術研究。 有能力維持區塊鏈開發人員部門的公司不太可能容忍這樣的指標。 但問題不僅在於吞吐量,還存在延遲。

潛伏

從交易發起到系統最終批准的延遲不僅取決於消息通過驗證和排序所有階段的速度,還取決於區塊形成參數。 即使我們的區塊鏈允許我們以 1000000 tps 的速度提交,但需要 10 分鐘才能形成 488MB 的區塊,這對我們來說會變得更容易嗎?

讓我們仔細看看 Hyperledger Fabric 中事務的生命週期,以了解什麼需要時間以及它與塊形成參數的關係。

輪對的分佈式註冊表:Hyperledger Fabric 的體驗
取自這裡: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) 客戶端形成一個交易,將其發送給背書節點,背書節點模擬交易(將鏈碼所做的更改應用到當前狀態,但不提交到賬本)並接收 RWSet - 密鑰名稱、版本和從CouchDB 中的集合中獲取的值,(2) 背書者將簽名的RWSet 發送回客戶端,(3) 客戶端檢查所有必要節點(背書者)的簽名,然後將交易發送到排序者服務,或者在沒有驗證的情況下發送(驗證稍後仍會進行),排序服務形成一個塊並且(4)發送回所有節點,而不僅僅是背書者; 節點檢查讀取集中的密鑰版本是否與數據庫中的版本、所有背書者的簽名相匹配,最後提交該塊。

但這還不是全部。 “orderer 形成區塊”這句話的背後不僅隱藏著交易的排序,還隱藏著從leader到follower並返回的連續3次網絡請求:leader在日誌中添加一條消息,發送給follower,後者添加到他們的日誌,向領導者發送成功複製的確認,領導者提交消息,向追隨者發送提交確認,追隨者提交。 區塊大小和時間越小,排序服務就越需要建立共識。 Hyperledger Fabric 有兩個區塊形成參數:BatchTimeout - 區塊形成時間和 BatchSize - 區塊大小(交易數量和區塊本身的大小(以字節為單位))。 一旦其中一個參數達到限制,就會發出一個新塊。 訂購者節點越多,花費的時間就越長。 因此,需要增加BatchTimeout和BatchSize。 但由於 RWSets 是版本化的,我們製作的塊越大,MVCC 衝突的可能性就越高。 此外,隨著 BatchTimeout 的增加,UX 會發生災難性的下降。 在我看來,解決這些問題的以下方案是合理且明顯的。

如何避免等待區塊最終確定並且不丟失交易狀態

形成時間和區塊大小越長,區塊鏈的吞吐量就越高。 一個並不直接跟隨另一個,但應該記住,在 RAFT 中建立共識需要從領導者到追隨者的三個網絡請求並返回。 訂單節點越多,花費的時間就越長。 區塊形成的大小和時間越小,這種相互作用就越多。 如何在不增加最終用戶系統響應時間的情況下增加形成時間和塊大小?

首先,您需要以某種方式解決由大塊大小引起的 MVCC 衝突,其中可能包含具有相同版本的不同 RWSets。 顯然,在客戶端(相對於區塊鍊網絡,這很可能是後端,我是認真的) MVCC 衝突處理程序,它可以是一個單獨的服務,也可以是帶有重試邏輯的事務啟動調用上的常規裝飾器。

重試可以採用指數策略來實現,但延遲也會呈指數下降。 因此,您應該在一定的小限制內使用隨機重試,或者使用恆定重試。 著眼於第一個變體中可能發生的碰撞。

下一步是使客戶端與系統的交互異步,這樣就不會等待 15、30 或 10000000 秒,我們將其設置為 BatchTimeout。 但同時,需要保持確保交易發起的更改被記錄/不記錄在區塊鏈中的能力。
數據庫可用於存儲事務的狀態。 最簡單的選擇是 CouchDB,因為它易於使用:該數據庫具有開箱即用的 UI、REST API,並且您可以輕鬆地為其設置複製和分片。 您可以在 Fabric 用於存儲其世界狀態的同一個 CouchDB 實例中創建一個單獨的集合。 我們需要存儲此類文檔。

{
 Status string // Статус транзакции: "pending", "done", "failed"
 TxID: string // ID транзакции
 Error: string // optional, сообщение об ошибке
}

該文檔在交易發送給對等方之前寫入數據庫,如果這是創建操作,則將實體 ID 返回給用戶(使用相同的 ID 作為鍵),然後是 Status、TxID 和 Error 字段當從同行收到相關信息時進行更新。

輪對的分佈式註冊表:Hyperledger Fabric 的體驗

在這個方案中,用戶不用等待區塊最終形成,只要觀看屏幕上旋轉的輪子10秒,他就會收到系統的即時響應並繼續工作。

我們選擇 BoltDB 來存儲事務狀態,因為我們需要節省內存,並且不想在與獨立數據庫服務器的網絡交互上浪費時間,特別是當這種交互使用純文本協議進行時。 順便說一句,無論您使用 CouchDB 來實現上述方案還是只是存儲世界狀態,無論如何,優化 CouchDB 中數據的存儲方式都是有意義的。 默認情況下,在 CouchDB 中,b 樹節點的大小為 1279 字節,遠小於磁盤上的扇區大小,這意味著讀取和重新平衡樹都將需要更多的物理磁盤訪問。 最佳尺寸符合標準 高級格式 大小為 4 KB。 為了優化,我們需要設置參數 btree_chunk_size 等於 4096 在 CouchDB 配置文件中。 對於BoltDB這樣的手動干預 它不需要.

背壓:緩衝策略

但可能會有很多消息。 除了圖中所示的服務之外,還與十幾個其他服務共享資源,這超出了系統的處理能力——即使在運行 Intellij Idea 極其乏味的機器上,所有這些都應該可以完美地工作。

通信系統、生產者和消費者的不同吞吐量的問題以不同的方式解決。 讓我們看看我們能做什麼。

刪除:我們可以聲稱能夠在 T 秒內處理最多 X 筆交易。 所有超過此限制的請求都會被丟棄。 這非常簡單,但是您可以忘記用戶體驗。

控制:消費者必須有一些接口,通過該接口,根據負載,他可以控制生產者的 tps。 不錯,但它給負載客戶端的開發人員帶來了實現此接口的義務。 對於我們來說,這是不可接受的,因為未來區塊鏈將被集成到大量長期存在的系統中。

緩衝:我們可以緩衝該流並以所需的速度處理它,而不是設法阻止輸入數據流。 顯然,如果我們想提供良好的用戶體驗,這是最好的解決方案。 我們使用 RabbitMQ 中的隊列實現了緩衝區。

輪對的分佈式註冊表:Hyperledger Fabric 的體驗

該方案中添加了兩個新操作:(1)收到 API 請求後,一條消息將與調用交易所需的參數一起排隊,並且客戶端收到一條消息,表明該交易已被系統接受,( 2 )後端以配置中指定的速度從隊列中讀取數據; 發起事務並更新狀態存儲中的數據。
現在,您可以根據需要增加構建時間和塊容量,從而向用戶隱藏延遲。

其他工具

這裡沒有提及鏈碼,因為它通常沒有什麼可以優化的。 鏈碼應該盡可能簡單和安全——這就是它所需要的全部。 該框架對我們簡單安全地編寫鏈代碼有很大幫助。 CSKit 來自 S7 Techlab 和靜態分析儀 復活^CC.

此外,我們的團隊正在開發一組實用程序,以使 Fabric 的使用變得簡單而愉快: 區塊鏈瀏覽器,效用為 自動網絡重新配置 (添加/刪除組織、RAFT 節點),實用程序 證書吊銷和身份刪除。 如果您願意貢獻,歡迎。

結論

這種方法可以輕鬆地將Hyperledger Fabric 替換為Quorum、其他私有以太坊網絡(PoA 甚至PoW),顯著降低實際吞吐量,但同時保持正常的UX(對於瀏覽器中的用戶和集成系統方面的用戶) )。 當方案中將 Fabric 替換為以太坊時,只需將重試服務/裝飾器的邏輯從處理 MVCC 衝突更改為原子隨機數增量並重新發送。 緩沖和狀態存儲使得將響應時間與塊形成時間解耦成為可能。 現在您可以添加數千個訂單節點,而不必擔心區塊形成過於頻繁並加載訂單服務。

總的來說,這就是我想分享的全部。 如果它對某人的工作有幫助,我會很高興。

來源: www.habr.com

添加評論