NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

Hyperledger Composer 评测

  • 2018-08-15
  • 本文字数:8725 字

    阅读完需:约 29 分钟

关键要点

  • 这项技术只适用于非常少量的场景。
  • 对于去中心化的分类账应用程序来说,Hyperledger Fabric 在验证写入批次时使用 MVCC(多版本并发控制)已经足够安全,但对于 B2C 初创公司来说还不够具有吸引力,因为这种方式可伸缩性不足。
  • 如果你可以保证所有交易的幂等性,那么就不必使用这项技术。
  • 这项技术仍然有些不成熟。
  • 尽管这是一个开源项目,但要真正应用到生产环境中,还需要更多云供应商的支持(这种情况可能会发生改变)。

Hyperledger Fabric 是一个具有三年历史的开源项目,大约两年前,它的代码库被迁移到 GitHub 上。我一直在关注这个开源项目。Hyperledger 项目由 Linux 基金会托管,并主要由 IBM 提供赞助。他们致力于推动使用私有或许可的区块链。在公共区块链中,第一个解决加密难题的匿名矿工可以将分类帐的下一个区块提交到链上,而私有区块链使用诸如 Raft Paxos 之类的算法解决共识问题。

在区块链中,你可以使用 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 文件夹中找到这个业务网络。



图 1:Feed7 组件(测试)

在这个业务网络模型中,broadcaster 是参与者。模型中还有 friendship、inbound 和 outbound 元素。friendship 用于捕获两个 broadcaster 之间的联系。每个 inbound 元素都是相关 broadcaster 的新闻项,而 outbound 元素是由 broadcaster 发出的新闻项。这个业务网络中有两个交易:broadcaster 之间可以交互,也可以向其他 broadcaster 发送新闻项。业务网络内唯一需要的查询是用于访问其他 broadcaster 的广播事务。

复制代码
async function broadcastParticipants(tx) {
const factory = getFactory();
const created = Date.now();
const now = new Date();
const k = tx.sender.participantId + '|' + created + '|';
const outboundRegistry = await getAssetRegistry('info.glennengstrand.Outbound');
const ok = 'Outbound:' + k + Math.random();
const inboundRegistry = await getAssetRegistry('info.glennengstrand.Inbound');
var o = factory.newResource('info.glennengstrand', 'Outbound', ok);
o.created = now;
o.subject = tx.subject;
o.story = tx.story;
o.sender = tx.sender;
await outboundRegistry.add(o);
const friends = await query('broadcasterFriends', { broadcaster: 'resource:info.glennengstrand.Broadcaster#' + tx.sender.participantId });
for (i = 0; i < friends.length; i++) {
const friend = friends[i];
const ik = 'Inbound:' + k + Math.random();
var inb = factory.newResource('info.glennengstrand', 'Inbound', ik);
inb.created = now;
inb.subject = tx.subject;
inb.story = tx.story;
inb.recipient = friend.to;
await inboundRegistry.add(inb);
}
}

代码示例 1:智能合约

在智能合约中调用的 Hyperledger Composer API 与 Node.js DApp 调用的 API 非常类似,但还是存在一些差别。在智能合约中需要使用 async/await 机制,而在 DApp 中需要使用 promise。智能合约必须使用预定义的查询,而 DApp 可以动态构建和运行查询。从 DApp 中查询或检索参与者或元素时,你必须将常量“PID:”作为密钥的一部分,但通过链代码访问相同的数据时则不需要。

复制代码
function submitTransaction(bizNetworkConnection, transaction, from, subject, story, callback, retry) {
const elastic = require('../repositories/elastic');
bizNetworkConnection.submitTransaction(transaction)
.then((result) => {
const retVal = {
"from": from,
"occurred": Date.now(),
"subject": subject,
"story": story
};
elastic.index(from, story);
callback(null, retVal);
}).catch(() => {
setTimeout(() => {
submitTransactionRetry(bizNetworkConnection, transaction, from, subject, story, callback, 2 * retry);
}, retry + Math.floor(Math.random() * Math.floor(1000)));
});
}
exports.addOutbound = function(args, callback) {
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
const bizNetworkConnection = new BusinessNetworkConnection();
bizNetworkConnection.connect(process.env.CARD_NAME)
.then((bizNetworkDefinition) => {
const factory = bizNetworkDefinition.getFactory();
var transaction = factory.newTransaction('info.glennengstrand', 'Broadcast');
transaction.sender = factory.newRelationship('info.glennengstrand', 'Broadcaster', 'PID:' + args.body.value.from);
transaction.subject = args.body.value.subject;
transaction.story = args.body.value.story;
submitTransaction(bizNetworkConnection, transaction, args.body.value.from, args.body.value.subject, args.body.value.story, callback, 2000);
});
}

代码示例 2:DApp 调用智能合约

你可能已经注意到,在提交事务时使用了重试逻辑。这是因为 Hyperledger Fabric 在验证写批次时使用了MVCC(多版本并发控制),很容易引发读取冲突错误,所以需要sleep 一段时间,然后重试提交事务。

在负载下测试微服务

统制和测试使用了相同的负载测试应用程序,你可以在代码库的 client/load 文件夹中找到它。负载测试在一个循环中创建了 10 个参与者,并为每个参与者提供两到四个朋友。它让每个参与者广播 10 个新闻项,每个新闻项由 150 个随机生成的数字组成。负载测试应用程序会启动三个线程,每个线程将 90%的时间用于生成新闻项,另外 10%用于测试搜索功能。

负载测试应用程序并不会直接调用新闻源微服务,而是调用一个名为 Kong 的开源 API 网关,这个网关将负载测试应用程序的请求代理给新闻源微服务。Kong 使用了 http-log 插件,以便将请求和响应日志发送到另一个微服务,后者又将与性能相关的部分批量发送到 Elasticsearch。你可以在 client/perf4 文件夹中找到 Kong 日志微服务的源代码。

我使用 Kibana 来可视化性能数据,包括吞吐量、平均延迟和百分位延迟。只要有可能,我总是会收集两小时内的性能指标摘要。



图 2:测试(即 Hyperledger Composer 和 Fabric)outbound 请求的每分钟吞吐量

图 3:测试(即 Hyperledger Composer 和 Fabric)outbound 请求的每分钟平均延迟

我进行了两次统制部署,每次都使用了 m4.xlarge 实例。其中有一次 feed4 服务运行在 Docker 容器中,而另一次则没有。使用 Docker 运行时吞吐量降低了 6%,但延迟几乎没有差别。我也进行了两次测试部署,使用 m4.xlarge 实例部署 Kong、Cassandra、Elasticsearch 和负载测试应用程序。第一次测试在 m4.xlarge 上部署了 Hyperledger Fabric、Composer、feed7 业务网络和微服务,第二次测试使用了 m4.2xlarge,以便比较扩展之后的性能差异。



图 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 秒。



图 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 项目都是开源项目,但在撰写本文时,要想应用到生产环境,云供应商提供的选项仍然很有限。

关于作者

Glenn Engstrand 是 Adobe 公司的软件架构师。他的工作重点是与工程师合作,提供可伸缩且符合 12 factor 标准的服务器端应用程序架构。Glenn 是 2018 年和 2017 年 Adobe 内部广告云开发者大会以及 2012 年波士顿 Lucene Revolution 大会的最受关注演讲者。他专注于将单体应用程序分解为微服务以及与实时通信基础设施的深度集成。

查看英文原文 Evaluating Hyperledger Composer

2018-08-15 18:306241
用户头像

发布了 731 篇内容, 共 434.4 次阅读, 收获喜欢 1997 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

fil有投资价值吗?投资fil的方式有哪些?

区块链 分布式存储 IPFS fil FIL投资

sql task01 环境搭建

橙橙橙橙汁丶

如何将知识引入机器学习模型提升泛化能力?

华为云开发者联盟

机器学习 算法 数据 模型 物理学

Hadoop安装与常用操作命令

Mike

堡垒机、防火墙以及跳板机分别是什么?

行云管家

云计算 运维 防火墙 堡垒机 跳板机

AOC萌新探索:搭建和体验在线AOC环境

华为云开发者联盟

Python 网络 自动化运维 AOC 网络设备

《程序员修炼之道 - 从小工到专家》吐血解读

博文视点Broadview

“遇见”未来“编程”语言,面向组件编程,送给在校学生

清风

Java 小程序 毕业设计

基于java springboot体育馆预约微信小程序源码(毕设)设计开发

清风

Java 小程序 源码 毕业设计

走!跟着浪潮云洲去挖矿

浪潮云

云计算

复旦大学附属中山医院钱琨:健康医疗大数据时代下的智慧医院建设

星环科技

大数据 医疗 数据能力

史上最全Linux可观测最佳实践分享!建议先收藏~

观测云

云计算 Linux

博文干货|5张图带你快速入门 Pulsar 的存储引擎 BookKeeper

Apache Pulsar

pulsar bookKeeper

出现吧,Python Web 菜谱系统的首页,不会前端技术,也能做

梦想橡皮擦

8月日更

架构实战营-模块二作业

俞立夫

架构实战营

2021,编程语言如何选择?

程序员鱼皮

Java c++ Python JavaScript Go 语言

摊牌了!哈利波特的“隐形斗篷”就是我想要的

百度开发者中心

人工智能 AI 最佳实践 行业资讯

【LeetCode】有效的字母异位词Java题解

Albert

算法 LeetCode 8月日更

MySQL 系列教程之(五)DDL 操作:建库建表

若尘

MySQL 数据库 8月日更

MySQL安全加固方法分享

Simon

MySQL 数据库 数据安全

30个Kafka常见错误小集合

王知无

爬虫遇到反爬机制怎么办? 看看我是如何解决的!

Python研究者

8月日更

能源区块链研究 | 加密行业碳抵消有助于大众接纳比特币吗?

CECBC

Android ANR应用无响应

W🌥

android 8月日更

技术加持、服务先行:北鲲云超算平台助力生命科学领域研究与发展

北鲲云

Vue进阶(三十八):v-for 中 :key 到底有什么用?

No Silver Bullet

Vue key 8月日更

合约量化交易系统开发技术

薇電13242772558

区块链

稳了!工业质检蝉联第一

百度大脑

智能制造

【SpringBoot技术专题】「JWT技术专区」SpringSecurity整合JWT授权和认证实现

洛神灬殇

spring security springboot JWT 8月日更

Hadoop生态系统

Mike

面向对象的原则是普遍适用么?

escray

学习 极客时间 如何落地业务建模 8月日更

Hyperledger Composer评测_ThoughtWorks_Glenn Engstrand_InfoQ精选文章