Hyperledger Composer評測

weixin_34127717發表於2018-08-15
\

關鍵要點

\\
  • 這項技術只適用於非常少量的場景。\\t
  • 對於去中心化的分類賬應用程式來說,Hyperledger Fabric在驗證寫入批次時使用MVCC(多版本併發控制)已經足夠安全,但對於B2C初創公司來說還不夠具有吸引力,因為這種方式可伸縮性不足。\\t
  • 如果你可以保證所有交易的冪等性,那麼就不必使用這項技術。\\t
  • 這項技術仍然有些不成熟。\\t
  • 儘管這是一個開源專案,但要真正應用到生產環境中,還需要更多雲供應商的支援(這種情況可能會發生改變)。\
\\

Hyperledger Fabric是一個具有三年曆史的開源專案,大約兩年前,它的程式碼庫被遷移到GitHub上。我一直在關注這個開源專案。Hyperledger專案由Linux基金會託管,並主要由IBM提供贊助。他們致力於推動使用私有或許可的區塊鏈。在公共區塊鏈中,第一個解決加密難題的匿名礦工可以將分類帳的下一個區塊提交到鏈上,而私有區塊鏈使用諸如RaftPaxos之類的演算法解決共識問題。

\\

在區塊鏈中,你可以使用CRUD的方式訪問分類帳。你還可以在分類帳上儲存被稱為智慧合約的迷你程式。當事務被提交給智慧合約時,在鏈程式碼中執行的所有分類帳狀態變更操作都具有原子性——要麼所有操作都被提交,要麼都不提交。如果鏈程式碼訪問的底層分類帳資料在鏈程式碼提交操作時發生變更,事務將被中止。這個過程是自動發生的,並且是智慧合約程式的重要組成部分。

\\

釋出Hyperledger Fabric的人還發布了另一個開源專案Hyperledger Composer,它讓開發人員可以輕鬆開發Hyperledger Fabric和DApps(去中心化應用程式)的鏈程式碼。

\\

為什麼是現在?

\\

Thoughtworks是一家技術諮詢公司(被Apax Partners收購),它把自己定位為“由一群充滿激情的人組成的社群,目的是徹底改變軟體的設計、開發和交付”。他們每年釋出兩次技術雷達報告,為是否暫停、評估、試用或採用某些特定的技術提供建議。第18卷技術雷達(Technology Radar)於2018年5月釋出,它將Hyperledger Composer放在試用環中。試用環的定義為“值得追求。非常有必要了解如何建立這種能力。企業應該在可以承擔風險的專案上嘗試這項技術“。

\\

作為軟體架構師,我對新興技術進行了評估,並將Hyperledger Composer放在我自己的技術雷達中。在評估一項新興技術時,我都會用它來實現一個簡單的新聞源微服務。這些微服務提供了相同的功能,並且可以通過完全相同的方式進行負載測試。通過這種方式,我就可以將某項技術與其他技術進行對比,從而總結出它們的效能特徵。我選擇了新聞源服務,因為它在社交網路中普遍存在,人們也非常熟悉,並且它足夠複雜,不是簡單的方案就能解決,但又足夠簡單易懂,不至於迷失在實現細節中。我在GitHub上釋出了這些微服務的原始碼,以及用於對它們進行負載測試、收集和分析效能結果所需的原始碼。本著同行評審的精神,我希望你們能夠拉取這些程式碼,並自己嘗試重現這些結果。

\\

構建測試微服務

\\

有了Hyperledger Composer,你就可以在伺服器端使用JavaScript開發智慧合約。它提供了一個原生客戶端庫,Node.js應用程式可以通過這個庫訪問分類帳,並將事務提交給智慧合約。出於實驗的目的,我使用已經開發好的Node.js微服務(請參閱程式碼庫中的server/feed4)作為統制。我將該微服務的原始碼複製到一個新資料夾中(請參閱程式碼庫中的server/feed7/micro-service),然後將所有對MySQL、Redis和Cassandra的引用替換為呼叫Hyperledger Composer客戶端API。feed7是這次實驗中的測試專案。兩個專案都使用了Elasticsearch,因為新聞訂閱服務的基本功能之一是基於關鍵字的搜尋,區塊鏈不適合用來實現這項功能。與這個程式碼庫中的其他大多數微服務一樣,feed7使用Swagger來定義REST API。該規範可以在server/swagger/news.yaml檔案中找到。

\\

你可以使用Hyperledger Composer建立一個由資料模型、運算元據模型的一組事務以及一組供事務訪問模型資料的查詢組成的業務網路。Hyperledger Composer可以與Hyperledger Fabric配合使用,Hyperledger Fabric的基本網路包括CouchDB、預設對等體、業務網路對等體、證照認證服務和orderer。feed7微服務在業務網路中訪問Hyperledger Fabric,你可以在server/feed7/business-network資料夾中找到這個業務網路。

\\

8ed1aa2023bba3c25e07299e4c70d9ab.jpg

\\

圖1:Feed7元件(測試)

\\

在這個業務網路模型中,broadcaster是參與者。模型中還有friendship、inbound和outbound元素。friendship用於捕獲兩個broadcaster之間的聯絡。每個inbound元素都是相關broadcaster的新聞項,而outbound元素是由broadcaster發出的新聞項。這個業務網路中有兩個交易:broadcaster之間可以互動,也可以向其他broadcaster傳送新聞項。業務網路內唯一需要的查詢是用於訪問其他broadcaster的廣播事務。

\\
\async function broadcastParticipants(tx) {\\tconst factory = getFactory();\\tconst created = Date.now();\\tconst now = new Date();\\tconst k = tx.sender.participantId + '|' + created + '|';\\tconst outboundRegistry = await getAssetRegistry('info.glennengstrand.Outbound');\\tconst ok = 'Outbound:' + k + Math.random();\\tconst inboundRegistry = await getAssetRegistry('info.glennengstrand.Inbound');\\tvar o = factory.newResource('info.glennengstrand', 'Outbound', ok);\\to.created = now;\\to.subject = tx.subject;\\to.story = tx.story;\\to.sender = tx.sender;\\tawait outboundRegistry.add(o);\\tconst friends = await query('broadcasterFriends', { broadcaster: 'resource:info.glennengstrand.Broadcaster#' + tx.sender.participantId });\\tfor (i = 0; i \u0026lt; friends.length; i++) {\   \t\t    const friend = friends[i];\    \t\tconst ik = 'Inbound:' + k + Math.random();\    \t\tvar inb = factory.newResource('info.glennengstrand', 'Inbound', ik);\    \t\tinb.created = now;\    \t\tinb.subject = tx.subject;\    \t\tinb.story = tx.story;\    \t\tinb.recipient = friend.to;\    \t\tawait inboundRegistry.add(inb);\\t}\}\
\\

程式碼示例1:智慧合約

\\

在智慧合約中呼叫的Hyperledger Composer API與Node.js DApp呼叫的API非常類似,但還是存在一些差別。在智慧合約中需要使用async/await機制,而在DApp中需要使用promise。智慧合約必須使用預定義的查詢,而DApp可以動態構建和執行查詢。從DApp中查詢或檢索參與者或元素時,你必須將常量“PID:”作為金鑰的一部分,但通過鏈程式碼訪問相同的資料時則不需要。

\\
\function submitTransaction(bizNetworkConnection, transaction, from, subject, story, callback, retry) {\\tconst elastic = require('../repositories/elastic');\\tbizNetworkConnection.submitTransaction(transaction)\    .then((result) =\u0026gt; {\    \tconst retVal = {\   \t   \t\"from\": from,\   \t   \t\"occurred\": Date.now(),\   \t   \t\"subject\": subject,\   \t   \t\"story\": story\    \t};\    \telastic.index(from, story);\    \tcallback(null, retVal);\    }).catch(() =\u0026gt; {\    \tsetTimeout(() =\u0026gt; {\   \t \tsubmitTransactionRetry(bizNetworkConnection, transaction, from, subject, story, callback, 2 * retry);\    \t}, retry + Math.floor(Math.random() * Math.floor(1000)));\   \t });\}\\exports.addOutbound = function(args, callback) {\  const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;\  const bizNetworkConnection = new BusinessNetworkConnection();\  bizNetworkConnection.connect(process.env.CARD_NAME)\\t.then((bizNetworkDefinition) =\u0026gt; {\    \t\tconst factory = bizNetworkDefinition.getFactory();\    \t\tvar transaction = factory.newTransaction('info.glennengstrand', 'Broadcast');\   \t\t    transaction.sender = factory.newRelationship('info.glennengstrand', 'Broadcaster', 'PID:' + args.body.value.from);\   \t\t    transaction.subject = args.body.value.subject;\    \t\ttransaction.story = args.body.value.story;\    \t\tsubmitTransaction(bizNetworkConnection, transaction, args.body.value.from, args.body.value.subject, args.body.value.story, callback, 2000);\\t});\}\
\\

程式碼示例2:DApp呼叫智慧合約

\\

你可能已經注意到,在提交事務時使用了重試邏輯。這是因為Hyperledger Fabric在驗證寫批次時使用了MVCC(多版本併發控制),很容易引發讀取衝突錯誤,所以需要sleep一段時間,然後重試提交事務。

\\

在負載下測試微服務

\\

統制和測試使用了相同的負載測試應用程式,你可以在程式碼庫的client/load資料夾中找到它。負載測試在一個迴圈中建立了10個參與者,併為每個參與者提供兩到四個朋友。它讓每個參與者廣播10個新聞項,每個新聞項由150個隨機生成的數字組成。負載測試應用程式會啟動三個執行緒,每個執行緒將90%的時間用於生成新聞項,另外10%用於測試搜尋功能。

\\

負載測試應用程式並不會直接呼叫新聞源微服務,而是呼叫一個名為Kong的開源API閘道器,這個閘道器將負載測試應用程式的請求代理給新聞源微服務。Kong使用了http-log外掛,以便將請求和響應日誌傳送到另一個微服務,後者又將與效能相關的部分批量傳送到Elasticsearch。你可以在client/perf4資料夾中找到Kong日誌微服務的原始碼。

\\

我使用Kibana來視覺化效能資料,包括吞吐量、平均延遲和百分位延遲。只要有可能,我總是會收集兩小時內的效能指標摘要。

\\

989725cd8a23cf3428022ce9082a185a.jpg

\\

圖2:測試(即Hyperledger Composer和Fabric)outbound請求的每分鐘吞吐量

\\

b3213a4f07f1754dc95174fb11911db7.jpg

\\

圖3:測試(即Hyperledger Composer和Fabric)outbound請求的每分鐘平均延遲

\\

我進行了兩次統制部署,每次都使用了m4.xlarge例項。其中有一次feed4服務執行在Docker容器中,而另一次則沒有。使用Docker執行時吞吐量降低了6%,但延遲幾乎沒有差別。我也進行了兩次測試部署,使用m4.xlarge例項部署Kong、Cassandra、Elasticsearch和負載測試應用程式。第一次測試在m4.xlarge上部署了Hyperledger Fabric、Composer、feed7業務網路和微服務,第二次測試使用了m4.2xlarge,以便比較擴充套件之後的效能差異。

\\

ee97c053ec2937af4fc57a370e3b0d55.jpg

\\

圖4:Feed7部署(測試)

\\

為了進行有效的比較分析,也因為生產配置不易獲得,所以統制和測試都使用了開發配置。AWS CloudFormation為Hyperledger Fabric提供了一個模板,但它只能用於部署基礎網路。除了IBM Cloud的廣告之外,我能夠找到的有關生產配置的唯一線上文件是VMware的一些人在Hacker Noon上發表的博文。博文中提供的生產配置和圖表表明,orderer使用了Kafka,但GitHub程式碼庫中的configtx.yaml檔案顯示的卻是獨立的OrdererType,而不是Kafka。說明那只是開發配置。原始碼中有一個註釋寫道:“獨立共識方案非常簡單,一個給定的鏈只需要一個共識者。它接收通過Order/Configure傳遞進來的訊息,對它們進行排序,然後使用blockcutter將訊息切成塊,再寫入指定的分類賬中”。

\\

效能結果

\\

對於Hyperledger來說,在負載測試效能方面,既有好的一面也有不好的一面。不好的一面:Hyperledger版本的新聞源在吞吐量上減少了300多倍,比傳統版本慢了三個數量級。好的一面是,增加一倍硬體能力讓吞吐量提高了20%,並將延遲幾乎減少了一半。

\\

統制每分鐘(RPM)持續傳送超過13,000個outbound請求(即新聞廣播),平均延遲為4毫秒,99百分位為9毫秒。對於m4.xlarge,測試平均每分鐘有29個outbound請求,而m4.2xlarge則為38。m4.xlarge的平均延遲為4.7秒,m4.2xlarge的平均延遲為3.2秒。對於m4.xlarge,99百分位延遲為10.2秒,對於m4.2xlarge,99百分位延遲為4.9秒。

\\

176aa9d7fd58f7db289a28102ad0f5f9.jpg

\\

圖5:outbound效能比較,延遲以毫秒為單位

\\

我還需要提到其他一些與效能低下有關的問題。統制程式的CPU和效能相關的指標很快就進入穩定狀態,而測試中的相同指標隨著時間的推移變得越來越糟。CPU的最大使用者是Fabric中的預設對等程式。這點令人感到驚訝,因為微服務總是訪問新聞源業務網路,但它對應的對等容器並不是CPU密集型的。也許預設對等體被用來支援交易?我找不到從配置中刪除它的方法。在生產配置中,你將擁有多個對等方,否則分類帳就不是去中心化的了。

\\

對於測試和統制,一旦SSD上的資料庫可用空間耗盡,微服務也就隨之崩潰。對於統制,在發出近3000萬個outbound請求後,Cassandra資料庫出現可用空間不足。對於測試,在發出大約4,000個outbound請求後,CouchDB資料庫出現可用空間不足。用於統制和測試的SSD儲存具有相同的容量,即20GB。顯然,儲存效率目前不是Hyperledger Fabric專案開發人員的主要關注點。

\\

結論

\\

最初,我認為新聞源應用程式將是區塊鏈的一個很好的用例。負載測試應用程式的主要操作是新增新聞項,這看起來非常類似於新增專案到分類帳。然而,現在,我認為這種類比是很膚淺的。區塊鏈的主要問題是防止所謂的雙重花費(double-spend)問題——如果區塊鏈不能阻止參與者兩次花同一筆錢,那它又有什麼用?對於公共區塊鏈,通過未使用的事務輸出或UTXO來處理這個問題。Hyperledger Fabric在驗證寫批次時通過對讀取集進行MVCC控制來解決這個問題。Fabric確實有效率問題,但效率問題可以等它發展成熟之後再來解決,不夠我認為使用MVCC來防止雙重花費是造成低吞吐量和高延遲的主要原因。因此,新聞源事務基本上是冪等的。如果兩個參與者以不同的順序或多次與自己交友,或者以不同的順序或多次向彼此廣播專案,並不會造成不良後果。Fabric分配了大量的CPU時間和記憶體來防止出現會對新聞源產生重大影響的問題。

\\

經過這次評估,我相信軟體開發的未來不會被區塊鏈吃掉。只有非常少的場景才需要這種高計算成本的自動化、有保證的分散式併發控制和驗證。基本上,你需要一個無法進行冪等交易的市場。現在評估Hyperledger Composer還算不錯,但以目前的成熟度來看,想要在不久的將來應用到生產中仍然是有問題的。Hyperledger專案都是開源專案,但在撰寫本文時,要想應用到生產環境,雲供應商提供的選項仍然很有限。

\\

關於作者

\\

d4b7a26acb7bbb360f14604ebf4f5166.jpgGlenn Engstrand 是Adobe公司的軟體架構師。他的工作重點是與工程師合作,提供可伸縮且符合12 factor標準的伺服器端應用程式架構。Glenn是2018年和2017年Adobe內部廣告雲開發者大會以及2012年波士頓Lucene Revolution大會的最受關注演講者。他專注於將單體應用程式分解為微服務以及與實時通訊基礎設施的深度整合。

\\

檢視英文原文Evaluating Hyperledger Composer

相關文章