摘要
预计区块链技术将对各种行业产生重大影响。然而,阻碍它们的一个问题是它们有限的交易吞吐量,特别是与诸如分布式数据库系统之类的已建立的解决方在本文中,我们重新构建了一个现代许可的区块链系统 Hyperledger Fabric,以将交易吞吐量从每秒 3,000 次增加到 20,000 次。我们专注于超出共识机制的性能瓶颈,我们提出架构更改,以减少交易排序和验证期间的计算和 I / O 开销,从而大大提高吞吐量。值得注意的是,我们的优化是完全即插即用的,不需要对 Hyperledger Fabric进行任何界面更改。
1. 介绍
区块链等分布式账本技术提供了一种以安全和可验证的方式进行交易的方法,而无需可信任的第三方。因此,人们普遍认为区块链将对金融、房地产、公共管理、能源和交通行业产生重大影响[1]。但是,为了在实践中可行,区块链必须支持与现有数据库管理系统支持的交易率相当的交易率,这可以提供一些相同的交易保证。
与不限制网络成员资格的无权限区块链相比,我们专注于许可的区块链,其中所有参与节点的身份都是已知的。许可的区块链适用于许多应用领域,包括融资;例如,Ripple 区块链旨在提供类似于当前 SWIFT 系统的货币兑换和跨银行交易的支付网络。
从技术角度来看,我们观察到这两种区块链之间的重要区别。无权区块链的无信任性质要求工作或利益证明,或昂贵的全球规模的拜占庭 – 容错共识机制[2]。最近的许多工作都集中在使这些更有效。另一方面,许可的区块链通常将共识和交易验证委托给选定的节点组,从而减轻了共识算法的负担。虽然在这种情况下,共识仍然是一个瓶颈,但最近正在解决这个问题 https://ripple.com 工作[3],[4],激励我们超越共识来确定进一步的绩效改进。
在本文中,我们批判性地研究了 Hyperledger Fabric 1.2 的设计,因为据报道它是最快的开源许可区块链[5]。虽然已经有一些关于优化 Hyperledger Fabric的工作,例如,使用积极的缓存[6],但我们并不知道任何先前关于重新构建系统的工作 2。因此,我们基于通用系统设计技术设计并实现了几种架构优化,这些技术将端到端交易吞吐量提高了近 7 倍,从每秒 3,000 到 20,000 个交易处理,同时减少了块延迟。我们的具体贡献如下:
1)从数据中分离元数据:Fabric中的共识层接收整个交易作为输入,但只需要交易 ID 来决定交易顺序。我们重新设计Fabric的交易排序服务,仅使用交易 ID,从而大大提高了吞吐量。
2)并行和缓存:交易验证的某些方面可以并行化,而其他方面可以从缓存数据中受益。我们重新设计了 Fabric 的验证服务,通过积极缓存调度器中的未编组块并通过并行化尽可能多的验证步骤,包括认可策略验证和语法验证。
3)利用存储器层次结构在关键路径上进行快速数据访问:Fabric 维护世界状态的键值存储可以用轻量级内存数据结构代替,其缺乏耐久性保证可以通过区块链本身进行补偿。我们围绕轻量级哈希表重新设计 Fabric 的数据管理层,该表可以更快地访问关键交易验证路径上的数据,从而将不可变块的存储推迟到写优化存储集群。 4)资源分离:提交者和背书者的对等角色争夺资源。我们介绍了一种将这些角色转移到单独硬件的架构。
重要的是,我们的优化不会违反 Fabric 的任何 API 或模块化边界,因此它们可以合并到 Fabric 版本 2.0 的计划版本中[7]。
2 有关相关工作的详细调查,请参阅第 V 节。
我们还概述了未来工作的几个方向,与我们提出的优化一起,有可能达到 Visa 等信用卡公司所要求的每秒 50,000 笔交易[2]。
在本文的其余部分,第二部分简要概述了 Hyperledger Fabric,第三部分介绍了我们的改进设计,第四部分讨论了实验结果,第五部分介绍了我们在先前工作中的贡献,第六部分总结了未来的发展方向工作。
2. Fabric 架构
作为由 Linux Foundation 托管的开源 Hyperledger 项目的一个项目,Fabric 是最活跃开发的许可区块链系统之一[8]。由于 Androulaki 等[9]详细描述了交易流程,因此我们仅提供一个简短的概要,重点介绍我们在第 III 节中提出改进的系统部分。
为了避免智能合约确定性的陷阱并允许即插即用的系统组件替换,Fabric 的结构与其他常见的区块链系统不同。交易遵循执行顺序提交流模式而不是公共顺序执行提交模式。客户端交易首先在沙箱中执行以确定它们的读写集,即由交易读取和写入的健值对集。然后,交易由排序服务排序,并最终验证并提交给区块链。此工作流程由分配了特定角色的节点实现,如下所述。
A. 节点类型
客户端发起交易,即对区块链的读取和写入,发送到 Fabric 节点。节点是 Peer 或排序者 Orderer;一些 Peer 也是背书者。所有 Peer 都将块提交到区块链的本地副本,并将相应的更改应用于维护当前世界状态快照的状态数据库。允许背书者节点根据链码,Fabric 的智能合约版本中捕获的业务规则来证明交易有效。排序者仅负责决定交易顺序,而不是正确性或有效性。
B. 交易流程
客户将其交易发送给一些背书者。每个背书者在沙箱中执行交易,并计算相应的读写集以及访问的每个键的版本号。每个背书者还使用业务规则来验证交易的正确性。客户等待足够数量的认可,然后将这些响应发送给排序服务的 Orderer。排序者首先就进入的交易的顺序达成共识,然后将消息队列分成块。块被传递给 Peer 节点,然后 Peer 验证并提交它们。由于其许可性质,所有节点必须已知并向成员服务提供商(MSP)注册,否则其他节点将忽略它们。
C. 实现细节
为了讨论第 III 节中的改进,我们现在仔细研究一下 orderer 和 peer 架构。
1)排序者:在收到来自背书者的回复后,客户端创建包含标题和有效负载的交易提议。标题包括交易 ID 和通道 ID。有效负载包括读写集和相应的版本号,以及支持的 Peer 节点的签名。交易提议使用客户的凭证签署并发送到排序服务。
排序服务的两个目标是(a)在交易顺序上达成共识,以及(b)将包含有序交易的块交付给提交者 Peer 节点。Fabric 目前使用 Apache Kafka(基于 ZooKeeper [10])来实现容错崩溃的共识。
排序者收到交易提案时,它会检查客户是否有权提交交易。如果是,则 orderer 将交易提议发布到 Kafka 集群,其中每个 Fabric 通道都映射到 Kafka 主题以创建相应的不可变的交易序列顺序。然后,每个排序者根据每个块允许的最大交易数或块超时周期将从 Kafka 接收的交易组装成块。使用 orderer 的凭证对块进行签名,并使用 gRPC [11]将其传递给 Peer 节点。
2)Peer:从排序服务接收消息时,Peer 首先从区块的头部和元数据检查其语法结构。然后检查 orderer 的签名是否符合指定的策略。任何这些测试失败的区块都会被立即丢弃。
在初始校验之后,区块被推入队列,保证其添加到区块链。但是,在此之前,区块会依次执行两个验证步骤和最后一个提交步骤。
在第一个验证步骤中,将解压缩块中的所有交易,检查其语法并验证其认可。未通过此测试的交易将被视为无效,但会保留在块中。此时,只有善意创建的交易仍然有效。
在第二个验证步骤中,Peer 确保有效交易之间的相互作用不会导致无效的世界状态。回想一下,每个交易都带有一组需要从世界状态数据库(它的读取集)读取的键,以及它将写入数据库(它的写集)的一组键和值,以及它们记录的版本号通过背书者。在第二个验证步骤中,交易的读写集中的每个键仍必须具有相同的版本号。从任何先前交易中写入该 Key 会更新版本号并使交易无效。这可以防止双重支出。
在最后一步中,Peer 将块(现在包括其交易的验证标志)写入文件系统。
Fabric 被虚拟化为多个通道,由通道 ID 识别。
Key 及其值(即世界状态)将保留在 LevelDB 或 CouchDB 中,具体取决于应用程序的配置。此外,每个块及其交易的索引都存储在 LevelDB 中以加速数据访问。
3. 设计
本节介绍我们对 Fabric 1.2 版的体系结构和实现的更改。该版本于 2018 年 7 月发布,随后于 2018 年 9 月发布 1.3 版,2019 年 1 月发布 1.4 版。但是,最近发布的版本中引入的更改不会影响我们的提议,因此我们预计在将我们的工作与新版本集成时不会有任何困难。重要的是,我们的改进使各个模块的接口和职责保持不变,这意味着我们的更改与现有的 Peer 或排序服务实现兼容。此外,我们的改进是相互正交的,因此可以单独实施。对于 Orderer 和 Peer,我们按照从最小到最大的性能影响的升序来描述我们的提议,与其对 Fabric 的各自更改相比。
A. 准备
使用拜占庭容错(BFT)一致性算法是HyperLedger中的关键性能瓶颈[2]。这是因为 BFT 一致性算法不能很好地与参与者的数量成比例。在我们的工作中,我们选择超越这个明显的瓶颈有三个原因:
•可以说,在许可的区块链中使用 BFT 协议并不像在无权限的系统中那么重要,因为所有参与者都是已知的并且被激励以保持系统以诚实的方式运行。
•正在广泛研究 BFT 共识[12],我们预计未来一两年内将出现更高吞吐量的解决方案。
•实际上,Fabric 1.2 不使用 BFT 共识协议,而是依赖于 Kafka 进行交易排序,如前所述。
出于这些原因,我们的工作目标不是使用更好的 BFT 一致性算法来提高 orderer性能,而是为了缓解当共识不再是瓶颈时出现的新问题。我们首先对排序服务提出两项改进,然后对 Peer 进行一系列改进。
B. Orderer 改进 I:从有效负载中分离交易头
在 Fabric 1.2 中,使用 Apache Kafka 的订购者将整个交易发送给 Kafka 进行订购。交易的长度可能是几千字节,导致高通信开销,从而影响整体性能。但是,就交易订单达成共识只需要交易 ID,因此我们可以通过仅向 Kafka 集群发送交易 ID 来获得订货人吞吐量的显着改善。
具体而言,在从客户端接收交易时,我们的订货人从标题中提取交易 ID 并发布图 1.新的订货人架构。传入的交易同时处理。他们的 TransactionID 被发送到 Kafka 集群进行订购。当接收到有序的 TransactionID 时,订货人用它们的有效负载重新组装它们并将它们收集到块中。
这个 ID 到 Kafka 集群。排序者将相应的有效负载分别存储在本地数据结构中,并在从 Kafka 收回 ID 时重新组装交易。随后,与 Fabric 一样,orderer 将交易集分段为块并将它们传递给 Peer。值得注意的是,我们的方法适用于任何共识实现,并且不需要对现有排序界面进行任何修改,从而允许我们利用现有的 Fabric 客户端和 Peer 代码。
C. Orderer 改进 II:消息流水线
在 Fabric 1.2 中,订购服务逐个处理来自任何给定客户端的传入交易。当交易到达时,识别其相应的信道,根据一组规则检查其有效性,并最终将其转发到共识系统,例如,卡夫卡;只有这样才能处理下一个交易。相反,我们实现了一个可以同时处理多个传入交易的流水线机制,即使它们来自使用相同 gRPC 连接的同一客户端。为此,我们维护一个线程池,它并行处理传入的请求,每个传入的请求都有一个线程。线程调用 Kafka API 来发布交易 ID,并在成功时向客户端发送响应。订货人完成的剩余处理与 Fabric 1.2 相同。
图 1 总结了新的排序设计,包括交易 ID 与有效负载的分离以及由于并行消息处理导致的横向扩展。
D. Peer 任务
回忆一下第 II-C2 节,在从排序者接收块时,Fabric Peer 按顺序执行以下任务:
•验证收到消息的合法性•验证块中每个交易的块头和每个认可签名•验证交易的读写集•更新 LevelDB 或 CouchDB 中的世界状态•将区块链日志存储在文件系统中,与 LevelDB 中的相应索引
我们的目标是在交易流程的关键路径上最大化交易吞吐量。为此,我们进行了广泛的调用图分析,以确定性能瓶颈。
图 2.新的 Peer 结构。快速 Peer 使用内存中的哈希表来存储世界状态。验证通道完全并发,并行验证多个块及其交易。代言人角色和持久存储被分成可扩展的集群,并由快速 Peer 给出经过验证的块。通道的所有部分都使用缓存中的未编组块。
我们做出以下观察。首先,验证交易的读写集需要快速访问 world 状态。因此,我们可以通过使用内存中的哈希表而不是数据库来加速该过程(第 III-E 节)。其次,交易流程不需要区块链日志,因此我们可以在交易流程结束时将其存储到专用存储和数据分析服务器(第 III-F 节)。第三,如果 Peer 也是背书者,则需要处理新的交易提案。但是,提交者和背书者角色是不同的,这使得为每项任务专用不同的物理硬件成为可能(第 III-G 节)。第四,必须在 Peer 验证和解决传入的块和交易。最重要的是,必须按顺序完成通过交易写入集验证状态更改,阻止所有其他任务。因此,尽可能加快这项任务非常重要(第 III-H 节)。
最后,通过缓存协议缓冲区[13]解块的结果(第 III-I 节),可以获得显着的性能提升。我们在图 2 中详细介绍了这种架构重新设计,包括其他提出的 Peer 改进。
E. Peer 改进 I:用哈希表替换世界状态数据库
必须为每个交易按顺序查找和更新世界状态数据库,以保证所有 Peer 的一致性。因此,对此数据存储的更新以尽可能高的交易速率发生是至关重要的。
我们认为,对于常见情况,例如跟踪分类帐上的钱包或资产,世界状态可能相对较小。即使需要存储数十亿个密钥,大多数服务器也可以轻松地将它们保存在内存中。因此,我们建议使用内存中的哈希表而不是 LevelDB / CouchDB 来存储世界状态。这样可以在更新世界状态时消除硬盘访问。它还消除了由于区块链本身的冗余保证而不必要的昂贵的数据库系统保证(即,ACID 属性),进一步提高了性能。当然,由于使用易失性存储器,这种替换易受节点故障的影响,因此必须通过稳定存储来增强内存中的哈希表。我们在第 III-F 节讨论了这个问题。
F.Peer 改进 II:使用对等集群存储块
通过定义,块是不可变的。这使它们非常适合仅附加数据存储。通过将数据存储与对等任务的其余部分分离,我们可以设想用于块和世界状态备份的多种类型的数据存储,包括在其文件系统中存储块和世界状态备份的单个服务器,如 Fabric 目前所做的那样;数据库或键值存储,如 LevelDB 或 CouchDB。为了实现最大扩展,我们建议使用分布式存储集群。请注意,使用此解决方案,每个存储服务器仅包含链的一小部分,从而激励使用分布式数据处理工具,如 Hadoop MapReduce 或 Spark5。
G.Peer 改进 III:单独承诺和认可
在 Fabric 1.2 中,endorser peer 也负责提交块。认可是一项昂贵的操作,承诺也是如此。虽然对一组背书者进行并发交易处理可能会提高应用程序性能,但在每个新节点上复制承诺的额外工作实际上无效了这一优势。因此,我们建议将这些角色分开。
具体而言,在我们的设计中,提交者节点执行验证通道,然后将经过验证的块发送给背书者群集,这些背书者仅将更改应用于其世界状态而无需进一步验证。此步骤允许我们释放 Peer 的资源。请注意,这种可以扩展以满足需求的背书者群集只会将对等方的认可角色分割为专用硬件。此群集中的服务器不等同于 Fabric 1.2 中的完整版本的背书节点。
H. Peer 改进 IV:并行化验证
块和交易头验证(包括检查发件人的权限,执行认可策略和语法验证)都是高度可并行化的。我们通过引入完整的验证通道来扩展 Fabric 1.2 的并发性。
具体而言,对于每个传入的块,一个 go-routine 被分配用于通过块验证阶段。随后,这些例程中的每一个都使用 Fabric 1.2 中已存在的 goroutine 池进行交易验证。因此,在任何给定时间,并行检查多个块及其交易的有效性。最后,所有读写集都由单个 goroutine 以正确的顺序依次验证。这使我们能够充分利用多核服务器 CPU 的潜力。但是,我们当前的实现不包括这样的存储系统。
I. Peer 增强 V: 缓存解析的区块
Fabric 使用 gRPC 在网络中让节点进行通信。Protocol Buffers 被用来进行序列化。为了保证处理应用和软件升级,Fabric 的区块结构是高度层级化的,每一个层级都是单独序列化和反序列化的。这将导致大量的内存将用来进行 byte 数组转成结构化的数据。而且,Fabric 1.2 没有在缓存中存储之前解析的数据,因此当需要这些数据的时候,这些工作将被重复执行。
为了缓解这个问题,我们计划用一个临时的缓存来存放解析的数据。区块会别缓存,无论当在校验管道还是通过区块号接收的时候。一旦区块的任何部分被解析了,它将会被存储到区块中以便再利用。我们用循环的缓存池实现这一功能,这是一个足够大的校验管道。无论区块是否被提交,一个新的区块可以被自动放进管道覆盖已经存在的位置的区块。由于在提交后不需要缓存,并且保证新块只在旧块离开管道后到达,所以这是一个安全的操作。注意解析操作只会在缓存中追加数据,不会修改。所以在校验通道里可以进行多线程的无锁操作。在最差的场景中,许多线程去读取同一个未被解析的数据,所有的程序并发的执行解析操作。接着最后写入缓存的线程获得胜利,这是没有问题的,因为大家执行的结果都是一致的。
调用图标分析,即使进行了这些操作,由于解析操作,内存占用率在执行期间仍然非常高。这是继 gRPC 调用和加密计算之后的占据最大的一项操作。但是后面 2 个操作,不在本次工作范围内。
4. 结果
本节介绍了对我们的体系结构改进的实验性性能评估。我们使用了 15 台本地服务器,通过 1 Gbit/s 交换机连接。每台服务器配备两个 2.10GHz 的 Intel R Xeon R CPU E5-2620 v2 处理器,总共 24 个硬件线程和 64 GB RAM。我们使用 Fabric1.2 作为基本情况,并逐步添加我们的改进以进行比较。默认情况下,fabric 配置为使用 leveldb 作为对等状态数据库,排序服务将已完成的块存储在内存中,而不是磁盘上。此外,我们不使用 Docker 容器来运行整个系统,以避免额外的开销。
虽然我们确保我们的实现不会更改 fabric 的验证行为,但所有测试都是使用不冲突且有效的交易运行的。这是因为有效交易必须经过每个验证检查,并且它们的写集将在提交期间应用于状态数据库。相反,可以删除无效的交易。因此,我们的结果评估了最坏情况下的性能。
对于专门针对排序者或提交者实验,我们分离了各自的系统部分。在 order 实验中,我们从客户机向 order 发送预加载的背书交易,并让一个模拟提交者简单地丢弃创建的块。类似地,在提交者的基准测试期间,我们将预加载的块发送给提交者,并为背书者和丢弃已验证块的块存储创建 mock。
然后,对于端到端的设置,我们实现了完整的系统:背书者根据来自提交人的已验证块的复制世界状态从客户端背书交易建议;订购人从背书交易创建块并将它们发送给提交人;提交者验证并提交对其内存中世界状态的更改,并将已验证的块发送给背书者和块存储;块存储使用结构 1.2 数据管理将块存储在其文件系统中,状态存储在 leveldb 中。但是,我们没有为可伸缩分析实现分布式块存储;这超出了本工作的范围。
为了进行公平的比较,我们对所有实验使用了相同的交易链码:每个交易模拟从一个帐户到另一个帐户的资金转移,读取并更改状态数据库中的两个键。这些交易的有效负载为 2.9kb,这是典型的[3]。此外,我们使用默认的背书政策,即接受单一背书人签名。
A. 通过 GRPC 传输数据块
我们首先对 GRPC 的性能进行基准测试。我们预先创建了包含不同交易数的有效块,通过 Fabric GRPC 接口将它们从 Orderer 发送到 Peer,然后立即丢弃它们。实验结果如图 3 所示。
我们发现,对于从 10 到 250 个交易的块大小(这是在以下部分中导致最佳性能的大小),交易吞吐量超过 40000 个交易/秒是可持续的。与第 IV-D 节中的端到端测试结果相比,很明显,在我们的环境中,网络带宽和服务器机架中使用的 1 Gbit/s 交换机不是性能瓶颈。
B. 作为消息大小函数的订购方吞吐量
在这个实验中,我们设置了多个客户机来向订购者发送事务,并监视发送 100000 个事务所需的时间。我们评估订单在订单 1.2 中的交易率,并将其与我们的改进进行比较:
•opt o-i:仅向卡夫卡发布事务 ID(第三-B 节)
•选择 O-II:来自客户的并行传入交易建议(第 III-C 节)
图 4 显示了不同负载大小的交易吞吐量。在 Fabric1.2 中,由于向 Kafka 发送大消息的开销,交易吞吐量随着负载大小的增加而降低。然而,当我们只将 Turac ID 发送给卡夫卡(OPT-O-1)时,对于 4096 kb 的有效负载大小,我们几乎可以将平均吞吐量(2.8×)增加三倍。添加优化 o-2 后,平均吞吐量比基础结构 1.2 提高 4 倍。特别是,对于 2kb 负载大小,我们将排序服务性能从 6215 个交易/秒提高到 21719 个交易/秒,比率接近 3.5x。
C. Peer 实验
在这一节中,我们描述了在孤立的单个 Peer 节点上的测试(我们在第 IV-D 节中展示了端到端评估的结果)。在这里,我们预先计算块并将它们发送给 Peer,就像我们在第 IV-A 节的 GRPC 实验中所做的那样。然后 Peer 完全验证并提交块。
与结构 1.2 相比,图中所示的三种配置累计包含了我们的改进(即,opt p-i i 包含 opt p-i,opt p-iii 包含了先前的两种改进):
•opt p-i leveldb 替换为内存哈希表
•opt p-ii 验证和提交完全并行化;块存储和背书分离,通过远程 GRPC 传输,分离存储服务器
•opt p-iii 所有解析的数据可以在校验和提交管道访问
1)固定块大小的实验:图 5 和图 6 显示了一次运行 100000 个交易的验证和提交结果,重复 1000 次。交易是收集到 100 个交易块中。我们先讨论延迟,然后是吞吐量。由于批处理,我们显示每个块的延迟,而不是每个交易延迟。结果与我们自己设定的目标一致,即不因吞吐量增加而引入额外的延迟;事实上,我们的性能改进将对等延迟减少到原始值的三分之一(请注意,这些实验没有考虑网络延迟)。虽然 opt p-ii 中引入的管道生成了一些额外的延迟,但是其他的优化并不能补偿它。
通过使用状态存储哈希表(opt p-i),我们能够将 Fabric1.2 对等机的吞吐量从 3200 个交易/秒增加到 7500 多个交易/秒。并行化 Val-idation(optp-ii)每秒增加了大约 2000 个交易操作。这是因为,如图 2 所示,只有前两个验证步骤可以并行化和缩放。因此,整个管道性能取决于读写集验证和提交的吞吐量。虽然使用 opt p-i 时承诺几乎是免费的,但是直到在 opt p-iii 中引入解组缓存,optp-ii 才有了回报。高速缓存大大减少了 cpu 的工作量,释放了并行验证额外块的资源。将所有 Peer 优化结合在一起,我们将 Peer 的提交性能提高了 7 倍,从大约 3200 个交易/秒提高到超过 21000 个交易/秒。
6.我们实验确定在该块大小上 Peer 吞吐量最大化。
2)参数敏感性:如第 IV-C 节所述,在 Peer 并行化块和交易验证至关重要。但是,不清楚要使性能最大化需要多少并行性。因此,我们探索一个 Peer 的性能可以通过改变两个参数来调谐的程度:
•验证管道中同时引导块的 go 例程的数量
•同时验证交易处理的 go 例程的数量
我们使用信号量控制系统中活动 go 协程的数量,同时允许多个块同时进入验证管道。这允许我们通过两个独立的 go 例程池来控制块头验证和交易验证中的并行级别。
对于 100 个交易的块大小,图 7 显示了改变 go 例程数量时的吞吐量。验证管道中的线程总数由两个独立轴的总和给出。例如,我们为管道中的 25 个交易验证 go 例程和 31 个并发块实现了最大吞吐量,总共为管道提供了 56 个 go 协程。当有太多线程时,我们会看到通过线程管理开销导致的性能小幅度下降,但是用太少的并行执行来耗尽 cpu 的代价是巨大的。因此,我们建议默认情况下,在给定的机器中,go 例程的数量至少是物理线程的两倍。
我们现在研究 Peer 吞吐量对块大小的依赖性。每个块大小实验是用先前测试的最佳调谐 GO 例程参数进行的。在 24±2 交易验证中使用的所有配置执行常规程序,并在管道中进行 30±3 个阻塞。同样,我们在给定大小的块中为一个基准测试运行分割 100000 个交易,并重复实验 1000 次。我们选择在对数尺度上扫描块大小空间以获得宽光谱的概述。
结果如图 8 所示。我们发现,块大小为 100 个交易/块时,以每秒 21000 多个交易的速度提供最佳吞吐量。我们还研究了与这个块大小的小偏差。我们发现块大小在 50 到 500 之间的性能差异非常小,因此我们选择将块大小固定为 100 个交易。
D.端到端吞吐量
我们现在讨论通过组合所有优化(即 opt)实现的端到端吞吐量。o-ii 与 opt 相结合。p-iii,与我们对未改性织物 1.2 的测量结果相比。
我们设置了一个使用三个 zookeeper 服务器和三个 kafka 服务器(默认主题复制因子为三)的集群的单个排序节点,并将其连接到 Peer。来自此 Peer 的块被发送到单个数据存储服务器,该服务器将世界状态存储在 leveldb 中,并将块存储在文件系统中。对于扩展,五个背书者复制对等状态并提供足够的吞吐量来处理客户端背书负载。最后,客户机安装在自己的服务器上;该客户机从五个背书服务器请求背书,并将背书事务发送到排序服务。这总共使用 15 台服务器连接到本地数据中心的同一个 1 Gbit/s 交换机。我们从客户端向排序方发送总计 100000 个已背书的交易,排序者将这些交易批处理为 100 个大小的块,并将它们传递给 Peer。为了估计吞吐量,我们测量 Peer 上提交的块之间的时间,并取一次运行的平均值。这些运行重复 100 次。表 1 显示,与我们的基线结构 1.2 基准相比,显著提高了 6-7 倍。
5. 相关工作
hyperledger fabric 是一个最近才开发的系统,它的架构仍在快速发展和重大变化中。因此,对于系统的性能分析或架构改进的建议方面的工作相对较少。在这里,我们综述了提高 Fabric 性能的最新技术。
最接近我们的工作是由 thakkar 等人[6]谁研究了各种配置参数对 Fabric 性能的影响。他们发现,主要的瓶颈是在背书策略验证期间重复验证 x.509 证书,对块中的交易进行顺序策略验证,以及在提交阶段进行状态验证。它们引入了对已验证的认可证书的积极缓存(合并到 Fabric 版本 1.1 中,因此是我们评估的一部分)、认可策略的并行验证以及批处理状态验证和承诺。这些改进使总吞吐量增加了 16 倍。我们还对提交方的验证进行了并行化,并进一步将状态数据库替换为更有效的数据结构,即哈希表。
hyperledger fabric 是一个最近才开发的系统,它的架构仍在快速发展和重大变化中。因此,对于系统的性能分析或架构改进的建议方面的工作相对较少。在这里,我们综述了提高 Fabric 性能的最新技术。
在最近的工作中,sharma 等人[14]研究了使用数据库技术,即事务重新排序和提前中止,来提高 fabric 的性能。他们关于早期识别冲突交易的一些想法与我们的想法是正交的,可以纳入我们的解决方案。但是,有些想法,例如让排序服务删除冲突交易,与我们的解决方案不兼容。首先,我们故意不向排序者发送交易读写集,只发送交易 id。其次,我们选择遵守 fabric 的设计目标,即将不同的任务分配给不同类型的节点,因此我们的排序服务不检查读写集的内容。未来工作的一个有趣方向是在不同的交易工作负载下比较这两种方法,以了解何时向排序服务发送完整交易详细信息的开销值得提前修剪冲突交易。
众所周知,由于拜占庭容错协议(bft)的消息通信开销,fabric 的 order 组件可能成为性能瓶颈。因此,在排序服务中使用 bft 协议的有效实现非常重要。sousa 等人[3]研究了著名的 bft-smart[15]实现作为 fabric 的一部分的使用,并表明,在单个数据中心内使用此实现,可以实现高达 30000 个交易/秒的吞吐量。然而,与我们的工作不同,Committer 组件没有基准测试,端到端的性能也没有得到解决。
Androulaki 等人[16]研究了通道在 Fabric 上的应用。然而,这项工作并没有提出一个绩效评估,以定量地确定其方法的效益。
raman 等人[17]研究了当区块链用于存储大型数据集分析产生的中间结果时,使用有损压缩来降低结构背书人和验证人之间共享状态的通信成本。然而,他们的方法只适用于对有损压缩不敏感的场景,这不是基于区块链的应用程序的一般情况。
一些研究已经检查了 Fabric 的性能,但没有提出内部结构的变化。例如,Dinh 等人使用 Blockbench[5]这一工具来研究私有区块链的性能,研究 Fabric 的性能,并将其与以太坊和奇偶校验的性能进行比较。他们发现,由于消息通道中的聚集,他们研究的结构版本没有扩展到超过 16 个节点。nasir 等人[18]比较了 fabric 0.6 和 1.0 的性能,发现 1.0 版本的性能优于 0.6 版本,这并不奇怪。Baliga 等人[19]表明,应用程序级参数(如交易的读写集大小、链码和事件负载大小)显著影响交易延迟。类似地,Pongnumkul 等人[20]比较了 Fabric 和以太坊对于加密货币工作负载的性能,发现 Fabric 在所有指标上都优于以太坊。bergman[21]将 fabric 与 apache cassandra 在类似环境中的性能进行了比较,发现对于少量 Peer 节点,fabric 在读重工作负载中的可线性化交易的延迟比 cassandra 低。另一方面,由于节点数量较多,或者写的工作负载很重,cassandra 有更好的性能。
6. 总结
这项工作的主要贡献是展示如何对每一个错误的 BuffStand 框架,如 HyffeDiger-Frand,可以重新设计,以支持每秒近20000个交易,一个比现有工作好 7 的因素。我们通过实现一系列独立的优化来实现这个目标,这些优化集中在 I/O、缓存、并行性和高效的数据访问上。在我们的设计中,排序服务只接收交易 id 而不是完整的交易,并且 Peer 上的验证是高度并行化的。我们还使用主动缓存,并利用轻量级数据结构在关键路径上快速访问数据。在未来的工作中,我们希望通过以下方式进一步提高 hyperledger fabric 的性能:
•结合有效的 bft 一致性算法,如 rcanopus[22]
•在不打开整个交易头的情况下,加快为排序服务提取交易 ID•替换现有的加密计算库,提供更有效率的库
•通过分配一个单独的每个通道的排序和快速 Peer 服务器
•使用分布式框架,如 apache spark[23]
引用
[1] V. Espinel, D. O’Halloran, E. Brynjolfsson, and D. O’Sullivan, “Deep shift, technology tipping points and societal impact,” in New York: World Economic Forum–Global Agenda Council on the Future of Software & Society (REF 310815), 2015.
[2] M. Vukolic ́, “The quest for scalable blockchain fabric: Proof-of-work vs. bft replication,” in International Workshop on Open Problems in Network Security. Springer, 2015, pp. 112–125.
[3] J. Sousa, A. Bessani, and M. Vukolic, “A Byzantine fault-tolerant ordering service for the hyperledger fabric blockchain platform,” in 2018 48th Annual IEEE/IFIP International Conference on Dependable Systems and Networks (DSN). IEEE, 2018, pp. 51–58.
[4] M. Yin, D. Malkhi, M. K. Reiter, G. Golan Gueta, and I. Abraham, “HotStuff: BFT Consensus in the Lens of Blockchain,” arXiv preprint arXiv:1803.05069, 2018.
[5] T. T. A. Dinh, J. Wang, G. Chen, R. Liu, B. C. Ooi, and K.-L. Tan, “BLOCKBENCH: A Framework for Analyzing Private Blockchains,” Proceedings of the 2017 ACM International Conference on Management of Data – SIGMOD ’17, pp. 1085–1100, 2017.
[6] P. Thakkar, S. Nathan, and B. Vishwanathan, “Performance Benchmarking and Optimizing Hyperledger Fabric Blockchain Platform,” arXiv, 2018.
[7] Hyperledger Fabric, “[FAB-12221] Validator/Committer refactor – Hyperledger JIRA.” [Online]. Available: https://jira.hyperledger.org/ browse/FAB- 12221?filter=12526
[8] C. Cachin, “Architecture of the hyperledger blockchain fabric,” in Workshop on Distributed Cryptocurrencies and Consensus Ledgers, vol. 310, 2016.
[9] E. Androulaki, A. Barger, V. Bortnikov, C. Cachin, K. Christidis, A. De Caro, D. Enyeart, C. Ferris, G. Laventman, Y. Manevich, S. Muralidharan, C. Murthy, B. Nguyen, M. Sethi, G. Singh, K. Smith, A. Sorniotti, C. Stathakopoulou, M. Vukolic ́, S. W. Cocco, and J. Yellick, “Hyperledger Fabric: A Distributed Operating System for Permissioned Blockchains,” Proceedings of the Thirteenth EuroSys Conference on – EuroSys ’18, pp. 1–15, 2018.
[10] ApacheFoundation,“ApacheKafka,ADistributedStreamingPlatform,” 2018. [Online]. Available: https://kafka.apache.org/ (Accessed 2018-12- 05).
[11] Cloud Native Computing Foundation, “gRPC: A high performance, open-source universal RPC framework,” 2018. [Online]. Available: https://grpc.io/
[12] S. Bano, A. Sonnino, M. Al-Bassam, S. Azouvi, P. McCorry, S. Meik- lejohn, and G. Danezis, “Consensus in the age of blockchains,” arXiv preprint arXiv:1711.03936, 2017.
[13] Google Developers, “Protocol Buffers — Google Developers,” 2018. [Online]. Available: https://developers.google.com/protocol-buffers/?hl= en
[14] A. Sharma, F. M. Schuhknecht, D. Agrawal, and J. Dittrich, “How to databasify a blockchain: the case of hyperledger fabric,” arXiv preprint arXiv:1810.13177, 2018.
[15] A. Bessani, J. Sousa, and E. Alchieri, “State machine replication for the masses with BFT-SMART,” in DSN, 2014, pp. 355–362.
[16] E. Androulaki, C. Cachin, A. De Caro, and E. Kokoris-Kogias, “Channels: Horizontal scaling and confidentiality on permissioned blockchains,” in European Symposium on Research in Computer Se-
curity. Springer, 2018, pp. 111–131.
[17] R. K. Raman, R. Vaculin, M. Hind, S. L. Remy, E. K. Pissadaki, N. K. Bore, R. Daneshvar, B. Srivastava, and K. R. Varshney, “Trusted multi- party computation and verifiable simulations: A scalable blockchain approach,” arXiv preprint arXiv:1809.08438, 2018.
[18] Q. Nasir, I. A. Qasse, M. Abu Talib, and A. B. Nassif, “Performance analysis of hyperledger fabric platforms,” Security and Communication Networks, vol. 2018, 2018.
[19] A. Baliga, N. Solanki, S. Verekar, A. Pednekar, P. Kamat, and S. Chat- terjee, “Performance Characterization of Hyperledger Fabric,” in Crypto Valley Conference on Blockchain Technology, CVCBT 2018, 2018.
[20] S. Pongnumkul, C. Siripanpornchana, and S. Thajchayapong, “Performance analysis of private blockchain platforms in varying workloads,” in 2017 26th International Conference on Computer Communications and Networks, ICCCN 2017. IEEE, 7 2017, pp. 1–6.
[21] S. Bergman, “Permissioned blockchains and distributed databases: A performance study,” Master’s thesis, Linkoping University, 2018.
[22] S. Keshav, W. M. Golab, B. Wong, S. Rizvi, and S. Gorbunov, “RCano- pus: Making canopus resilient to failures and byzantine faults,” arXiv preprint arXiv:1810.09300, 2018.
[23] Apache Foundation, “Apache Spark – Unified Analytics Engine for Big Data,” 2018. [Online]. Available: https://spark.apache.org