核心概念 - 交易排序服务
本主题从概念上介绍了交易排序的概念,交易排序器如何与对端节点交互,他们在交易流中扮演的角色以及交易排序服务的当前可用实现的概述,尤其着重于 Raft 交易排序服务的实现。
1. 什么是交易排序
以太坊和比特币等许多分布式区块链,是无需许可制的,这意味着任何节点都可以参与共识过程,在此过程中,交易被排序并打包成区块。因此,这些系统依赖于概率共识算法 (probabilistic consensus algorithm),该算法最终可以很高的概率确保达到帐本的一致性,但是仍然容易受到帐本分叉的影响,因为网络中的不同参与者对接受的交易顺序具有不同的视图。
Hyperledger Fabric 的工作原理有所不同。它具有一种称为交易排序器的节点来执行交易排序,该节点与其他节点一起构成交易排序服务。由于 Fabric 的设计依赖于确定性共识算法 (deterministic consensus algorithm),因此对端节点验证的由交易排序服务生成的任何区块都可以保证是最终且正确的。账本无法像在其他许多分布式区块链中那样分叉。
除了提高确定性之外,将链码执行的背书 (在对端点发生) 与交易排序分开可以为 Fabric 提供性能和可伸缩性方面的优势,消除了在同一节点执行交易和交易排序时可能出现的瓶颈。
2. 交易排序器节点和通道配置
除其交易排序角色外,交易排序器还维护被允许创建通道的组织的列表。该组织列表称为“联盟”,该列表本身保留在“交易排序器系统通道”的配置中。默认情况下,该列表及其所处的通道只能由交易排序器管理员编辑。请注意,交易排序服务可能会保留其中几个列表,这使该联盟成为 Fabric 多租户的工具。
交易排序器还对通道实施基本的访问控制,从而限制了谁可以对其进行读写数据以及谁可以对其进行配置。请记住,有权修改通道中的配置元素的人员必须受相关管理员在创建联盟或通道时设置的策略的约束。配置交易由交易排序器处理,因为交易排序器需要知道当前策略集才能执行其基本形式的访问控制。在这种情况下,交易排序器将处理配置更新,以确保请求者具有适当的管理权限。如果是这样,则交易排序器针对现有配置验证更新请求,生成新的配置交易,并将其打包到一个区块中,该区块中继到通道上的所有对端节点。然后,对端节点处理配置交易,以验证交易排序器批准的修改确实确实满足通道中定义的策略。
3. 交易排序器节点和身份标识
与区块链网络交互的所有事物 (包括对端节点,应用程序,管理员和交易排序器) 都从其数字证书和其成员资格服务提供商 (Membership Service Provider, MSP) 定义中获取其组织身份。
有关身份和 MSP 的更多信息,请查看有关 身份 和 MSP 的文档。
就像对端节点一样,交易排序节点属于组织。与对端节点一样,每个组织都应使用单独的证书颁发机构 (Certificate Authority, CA)。此 CA 是否将充当根 CA,还是你选择部署根 CA,然后选择与该根 CA 关联的中间 CA,取决于你。
4. 交易排序器和交易流程
4.1 第一阶段:提案
我们从 对端节点 主题中看到,它们构成了区块链网络的基础,托管了帐本,应用程序可以通过智能合约对其进行查询和更新。
具体来说,想要更新帐本的应用程序涉及三个阶段的过程,以确保区块链网络中的所有对端节点都保持其帐本彼此一致。
在第一阶段,客户端应用程序将交易提案发送给对端节点的子集,该对端节点将调用智能合约以产生提案的账本更新,然后对结果进行背书。背书的对端节点目前不将提案的更新应用于其账本副本。相反,背书的对端节点将提案响应返回到客户端应用程序。背书的交易提案将最终在第二阶段按顺序排列,然后分发给所有对端节点以进行最终验证并在第三阶段进行提交。
要深入了解第一阶段,请参考 对端节点 主题。
4.2 第二阶段:将交易排序和打包成区块
在交易的第一阶段完成之后,客户端应用程序已收到来自一组对端节点的背书交易提案响应。现在该进行交易的第二阶段了。
在此阶段,应用程序客户端将包含背书交易提案响应的交易提交到交易排序服务节点。交易排序服务创建交易区块,最终将这些交易区块分发给通道上的所有对端节点,以进行最终验证并在第三阶段进行提交。
交易排序服务节点同时接收来自许多不同应用程序客户端的交易。这些交易排序服务节点一起工作以共同形成交易排序服务。它的工作是将提交的交易的批处理按定义明确的顺序排列,然后打包成区块。这些区块将成为区块链的区块!
区块中的交易数量取决于与区块的所需大小和最大经过时间有关的通道配置参数 (准确地说是 BatchSize 和 BatchTimeout 参数)。然后,将这些区块保存到交易排序器的帐本中,并分发给已加入该通道的所有对端节点。如果对端节点此时恰好处于关闭状态,或者稍后加入了该通道,则在重新连接到交易排序服务节点后,或者与另一对端节点 gossiping,它将接收到区块。我们将在第三阶段看到对端节点如何处理此区块。
交易排序节点的第一个角色是打包提案的帐本更新。在上面的示例中,应用程序 A1 将由 E1 和 E2 背书的交易 T1 发送给交易排序器 O1。并行地,应用程序 A2 将由 E1 背书的交易 T2 发送到交易排序器 O1。O1 将来自应用程序 A1 的交易 T1 和来自应用程序 A2 的交易 T2 以及来自网络中其他应用程序的其他交易打包到区块 B2 中。我们可以看到,在 B2 中,交易顺序为 T1,T2,T3,T4,T6,T5 – 可能不是这些交易到达交易排序器的顺序! (此示例显示了非常简化的交易排序服务配置,其中只有一个交易排序器节点。)
值得注意的是,一个区块中的交易顺序不一定与交易排序服务所接收的交易顺序相同,因为可能有多个交易排序服务节点大约在同一时间接收交易。重要的是,交易排序服务将交易置于严格的顺序中,对端节点将在验证和提交交易时使用此顺序。
区块内交易的这种严格排序使 Hyperledger Fabric 与其他区块链略有不同,在其他区块链中,同一笔交易可以打包成多个不同的区块,竞争形成一个链。在 Hyperledger Fabric 中,交易排序服务生成的区块是最终的。一旦将交易写入一个区块,就可以确保其在账本中的位置。正如我们之前所说,Hyperledger Fabric 的确定性意味着没有账本分叉 - 验证的交易将永远不会被还原或丢弃。
我们还可以看到,尽管对端节点执行智能合约并处理交易,但交易排序器绝对不会这样做。到达交易排序器的每个授权交易都被打包在一个区块中 - 交易排序器不对交易的内容做出判断 (如前所述,通道配置交易除外)。
在第二阶段结束时,我们看到交易排序器负责简单但至关重要的过程,这些过程包括收集提案的交易更新,进行交易排序并将它们打包成区块以便分发。
4.3 第三阶段:验证和提交
交易工作流程的第三阶段涉及从交易排序器到对端节点的区块的分发和后续验证,在这里可以将它们应用于帐本。
阶段 3 从交易排序器将区块分配给与其连接的所有对端节点开始。还值得注意的是,并非每个对端节点都需要连接到交易排序器,对端节点可以使用 gossip 协议将区块级联到其他对端节点。
每个对端节点将独立地但以确定性的方式验证分布式区块,以确保账本保持一致。具体来说,通道中的每个对端节点都将验证区块中的每个交易,以确保其已被所需组织的对端节点认可,其背书相匹配,并且未被其他最近提交的交易 (可能已经在交易中进行的交易) 使之无效。无效的交易仍保留在交易排序器创建的不可变区块中,但它们被对端节点标记为无效,并且不会更新帐本的状态。
交易排序节点的第二个作用是将区块分配给对端节点。在该示例中,交易排序器 O1 将区块 B2 分配给对端节点 P1 和对端节点 P2。对端节点 P1 处理区块 B2,从而将新区块添加到 P1 上的帐本 L1。并行地,对端节点 P2 处理区块 B2,导致将新区块添加到 P2 上的帐本 L1。一旦该过程完成,账本 L1 就已在对端节点 P1 和 P2 上进行了一致更新,并且每个账本可以通知连接的应用程序交易已被处理。
总而言之,在第三阶段中,交易排序服务生成的区块始终应用于帐本。严格按顺序将交易划分为区块,每个对端节点都可以验证交易更新是否在整个区块链网络中得到一致应用。
要深入了解第三阶段,请返回 对端节点 主题。
5. 交易排序服务实现
尽管当前可用的每个交易排序服务都以相同的方式处理交易和配置更新,但是仍然存在几种不同的实现方式,用于在交易排序服务节点之间对严格的交易排序达成共识。
有关如何启动交易排序节点的信息 (无论将使用哪种实现节点),请查阅 我们有关启动交易排序节点的文档。
-
Solo
交易排序服务的 Solo 实现被恰当地命名:它仅具有一个交易排序节点。结果,它不是,而且永远不会是容错的。因此,无法将 Solo 实现用于生产,但它们是测试应用程序和智能合约或创建概念证明 (Proof of Concept) 的理想选择。但是,如果你想将此 PoC 网络扩展到生产环境中,则可能要从一个单节点 Raft 群集开始,因为它可能已重新配置为添加其他节点。
-
Raft
从 v1.4.1 开始,Raft 是一项新的功能,它是基于
etcd
中 Raft 协议实现的崩溃容错 (Carsh Fault Tolerant, CFT) 交易排序服务。Raft 遵循“领导者和跟随者”模型,其中 (每个通道) 选举领导者节点,并由跟随者复制其决策。与基于 Kafka 的交易排序服务相比,Raft 交易排序服务应该更易于设置和管理,并且其设计允许不同的组织将节点贡献给分布式交易排序服务。 -
Kafka
类似于基于 Raft 的交易排序,Apache Kafka 是一种 CFT 实现,它使用“领导者和跟随者”节点配置。Kafka 利用 ZooKeeper 集合进行管理。从 Fabric v1.0 开始可以使用基于 Kafka 的交易排序服务,但是许多用户可能会发现管理 Kafka 群集的额外管理开销令人生畏或不受欢迎。
6. Solo
如上所述,开发测试,开发或概念证明网络时,Solo 交易排序服务是一个不错的选择。因此,它是我们 构建你的第一个网络教程 中部署的默认交易排序服务),因为从其他网络组件的角度来看,Solo 交易排序服务与更复杂的 Kafka 和 Raft 实施相同地处理交易,同时节省了管理费用,维护和升级多个节点和群集的开销。由于 Solo 交易排序服务不具有崩溃容错功能,因此永远不应将其视为生产区块链网络的可行替代方案。对于只希望从单个交易排序节点开始但将来可能会增长的网络,单个节点 Raft 群集是一个更好的选择。
7. Raft
有关如何配置 Raft 交易排序服务的信息,请查看我们的 有关配置 Raft 交易排序服务的文档。
生产网络的交易排序服务选择,已建立的 Raft 协议的 Fabric 实现使用“领导者和跟随者”模型,在该模型中,领导者是在通道中的交易排序节点之间动态选举的 (这种节点集合称为“同意集”),并且该领导者将消息复制到跟随者节点。只要有剩余的大多数交易排序节点 (称为“仲裁”),系统就可以承受包括领导节点在内的所有节点的损失,因此 Raft 被称为“故障容错” (Crash Fault Tolerant, CFT)。换句话说,如果一个通道中有三个节点,则它可以承受一个节点的丢失 (剩下两个)。如果通道中有五个节点,则可能会丢失两个节点 (剩下三个剩余节点)。
从它们提供给网络或通道的服务的角度来看,Raft 与现有的基于 Kafka 的交易排序服务 (我们将在后面讨论)相似。它们都是采用领导者和跟随者设计的 CFT 交易排序服务。如果你是应用程序开发人员,智能合约开发人员或对端节点管理员,则不会注意到基于 Raft 和 Kafka 的交易排序服务之间的功能差异。但是,有一些主要差异值得考虑,尤其是如果你打算管理交易排序服务:
- Raft 更容易安装。尽管 Kafka 拥有许多崇拜者,但即使是那些崇拜者,他们也通常会承认部署 Kafka 集群及其 ZooKeeper 集成可能很棘手,这需要在 Kafka 基础架构和设置方面具有高水平的专业知识。此外,与 Raft 相比,Kafka 需要管理的组件更多,这意味着出错的地方更多。 Kafka 有其自己的版本,必须与你的交易排序器协调。使用 Raft,一切都将嵌入到你的交易排序节点中。
- Kafka 和 Zookeeper 并非旨在跨大型网络运行。它们被设计为 CFT,但应在紧密的主机中运行。这就是说,实际上,你需要一个组织来运行 Kafka 集群。鉴于此,在使用 Kafka (Fabric 支持) 的情况下,让交易排序节点由不同的组织运行不会带来很多分散性,因为节点将全部进入同一组织控制下的同一 Kafka 集群。借助 Raft,每个组织都可以拥有自己的交易排序节点,参与交易排序服务,从而导致系统更加分散。
- Raft 本身受支持。尽管基于 Kafka 的交易排序服务当前与 Fabric 兼容,但要求用户获取必需的镜像并了解如何自行使用 Kafka 和 ZooKeeper。同样,对 Kafka 相关问题的支持是通过 Apache,Kafka 的开源开发人员,而不是 Hyperledger Fabric 来进行的。另一方面,已经开发了 Fabric Raft 实现,并将在 Fabric 开发人员社区及其支持机构中提供支持。
- Kafka 使用服务器池 (称为 “Kafka 经纪人”),而交易排序器组织的管理员指定他们要在特定通道上使用多少个节点,Raft 允许用户指定将哪个交易排序节点部署到哪个通道。这样,对端节点组织可以确保,如果他们还拥有一个交易排序器,则将该节点作为该通道的交易排序服务的一部分,而不是信任并依靠中央管理员来管理 Kafka 节点。
- Raft 是 Fabric 开发拜占庭式容错 (Byzantine Fault Tolerant, BFT) 交易排序服务的第一步。就像我们将看到的那样,Raft 开发中的某些决定是由此驱动的。如果你对 BFT 感兴趣,则学习如何使用 Raft 应该可以简化过渡过程。
注意:与 Solo 和 Kafka 相似,Raft 交易排序服务在收到回执后会丢失交易。例如,如果领导者大约在追随者提供收据确认的同时崩溃。因此,应用程序客户端无论如何都应在对端节点上侦听交易提交事件 (以检查交易的有效性),但应格外小心,以确保客户端也能容忍超时,该超时不会在配置的时间范围内落实交易。取决于应用程序,可能希望在这种超时情况下重新提交交易或收集一组新的背书。
7.1 Raft 概念
尽管 Raft 提供了许多与 Kafka 相同的功能 - 尽管采用了更简单易用的包装 - 但在 Kafka 的掩盖下其功能却大不相同,并向 Fabric 引入了许多新概念或对现有概念的扭曲。
日志条目 (Log Entry)。 Raft 交易排序服务中的主要工作单元是“日志条目”,此类条目的完整顺序称为“日志”。如果大多数成员 (换言之为法定人数) 同意条目及其顺序,则我们认为日志是一致的,从而使复制了各种交易排序器的日志。
同意集 (Contenter set)。交易排序节点积极参与给定通道的共识机制,并接收该通道的复制日志。这可以是所有可用节点 (在单个群集中或在组成系统通道的多个群集中),也可以是那些节点的子集。
有限状态机 (Finite-State Machine, FSM)。 Raft 中的每个交易排序节点都有一个 FSM,并共同使用它们来确保各个交易排序节点中的日志顺序是确定性的 (以相同顺序编写)。
法定人数 (Quorum)。描述需要确认提案以允许交易排序交易的最小同意者数量。对于每个同意集,这是大多数节点。在具有五个节点的群集中,三个群集必须可用。如果由于某种原因无法达到法定数量的节点,则交易排序服务集群将无法用于通道上的读取和写入操作,并且无法提交任何新日志。
领导者 (Leader)。这不是一个新概念 - 正如我们所说的,Kafka 还使用了领导者 - 但至关重要的是要了解,在任何给定时间,通道的同意者集会选举一个节点作为领导者 (稍后我们将在 Raft 中描述这种情况是如何发生的)。负责人负责摄取新的日志条目,将它们复制到跟随者交易排序节点,并管理何时将条目视为已提交。这不是交易排序器的特殊类型。这只是交易排序器可能在某些时候扮演的角色,而在其他情况下 (视情况而定) 则没有。
跟随者 (Follower)。同样,这不是一个新概念,但了解跟随者的关键是跟随者从领导者那里接收日志并确定性地复制它们,以确保日志保持一致。正如我们在领导者选举部分中所看到的那样,跟随者还会从领导者那里收到“心跳”消息。如果领导者在可配置的时间内停止发送这些消息,则跟随者将发起领导者选举,其中一个将被选举为新领导者。
7.2 交易流程中的 Raft
每个通道都在 Raft 协议的单独实例上运行,该协议允许每个实例选举不同的领导者。在群集由不同组织控制的交易排序节点组成的用例中,此配置还允许进一步分散服务。尽管所有 Raft 节点都必须是系统通道的一部分,但不一定必须是所有应用程序通道的一部分。通道创建者 (和通道管理员) 可以选择可用交易排序器的子集,并根据需要添加或移除交易排序节点 (只要一次仅添加或移除一个节点)。
尽管此配置以冗余心跳消息和 goroutine 的形式创建了更多开销,但为 BFT 奠定了必要的基础。
在 Raft 中,交易 (以提议或配置更新的形式) 由接收交易的交易排序节点自动路由到该通道的当前负责人。这意味着对端节点和应用程序不需要在任何特定时间知道谁是领导者节点。仅交易排序节点需要知道。
完成交易排序器验证检查后,将按照我们的交易流程第二阶段中的说明对交易进行排序,打包,成区块同意和分发。
7.3 体系结构注解
Raft 中领导人选举的工作方式
尽管选举领导者的过程是在交易排序器的内部流程中进行的,但值得注意的是该流程是如何进行的。
Raft 节点始终处于以下三种状态之一:跟随者,候选者或领导者。所有节点最初都是作为跟随者开始的。在这种状态下,他们可以接受来自领导者的日志条目 (如果已当选),或为领导者投票。如果在设定的时间段内 (例如,五秒钟) 未接收到日志条目或心跳,则节点会自动升级为候选状态。在候选状态下,节点向其他节点请求投票。如果候选人获得法定人数的选票,则将其晋升为领导人。领导者必须接受新的日志条目并将其复制到跟随者。
有关领导者选举过程工作方式的直观图示,请查看 The Secret Lives of Data。
快照
如果交易排序节点出现故障,它如何获取重新启动时丢失的日志?
尽管可以无限期地保留所有日志,但是为了节省磁盘空间,Raft 使用了一个称为“快照”的过程,用户可以在其中定义将在日志中保留多少字节的数据。此数据量将符合一定数量的区块 (取决于区块中的数据量。请注意,快照中仅存储完整的区块)。
例如,假设滞后的副本 R1 刚刚重新连接到网络。它的最新区块是 100。领导者 L 在区块 196,并配置为以在这种情况下表示 20 个区块的数据量进行快照。因此,R1 将从 L 接收区块 180,然后发出对区块 101 至 180 的传递请求。然后,将通过常规 Raft 协议将区块 180 至 196 复制到 R1。
7.4 Kafka
Fabric 支持的另一个崩溃容错交易排序服务是对 Kafka 分布式流平台的改编,可以用作交易排序节点的集群。你可以在 Apache Kafka 网站上了解有关 Kafka 的更多信息,但在较高层次上,Kafka 使用与 Raft 相同的概念“领导者和跟随者”配置,在该配置中,交易 (被 Kafka 称为“消息”) 从领导者复制而来。节点到跟随者节点。如果领导者节点发生故障,则跟随者之一将成为领导者,交易排序可以继续进行,从而确保了容错能力,就像 Raft 一样。
Kafka 集群的管理,包括任务的协调,集群成员,访问控制和控制器选举等,均由 ZooKeeper 集成及其相关 API 进行处理。
众所周知,Kafka 集群和 ZooKeeper 集成很难设置,因此我们的文档假定你对 Kafka 和 ZooKeeper 有一定的了解。如果你决定在没有专业知识的情况下使用 Kafka,则在尝试使用基于 Kafka 的交易排序服务之前,至少应完成《 Kafka快速入门》 指南的前六个步骤。你也可以查阅此样本配置文件,以简要了解 Kafka 和 ZooKeeper 的合理默认值。
要了解如何启动基于 Kafka 的交易排序服务,请查看 我们有关 Kafka 的文档。
Reference
- Docs » Key Concepts » The Ordering Service, https://hyperledger-fabric.readthedocs.io/en/release-1.4/orderer/ordering_service.html
- Docs » Key Concepts » Identity, https://hyperledger-fabric.readthedocs.io/en/release-1.4/identity/identity.html
- Docs » Key Concepts » Membership, https://hyperledger-fabric.readthedocs.io/en/release-1.4/membership/membership.html
- Docs » Key Concepts » Peers, https://hyperledger-fabric.readthedocs.io/en/release-1.4/peers/peers.html
- Docs » Architecture Reference » Gossip data dissemination protocol, https://hyperledger-fabric.readthedocs.io/en/release-1.4/gossip.html
- Docs » Operations Guides » Setting up an ordering node, https://hyperledger-fabric.readthedocs.io/en/release-1.4/orderer_deploy.html
- Docs » Tutorials » Building Your First Network, https://hyperledger-fabric.readthedocs.io/en/release-1.4/build_network.html
- Docs » Operations Guides » Configuring and operating a Raft ordering service, https://hyperledger-fabric.readthedocs.io/en/release-1.4/raft_configuration.html
- https://kafka.apache.org/
- The Secret Lives of Data, http://thesecretlivesofdata.com/raft/
- Docs » Operations Guides » Bringing up a Kafka-based Ordering Service, https://hyperledger-fabric.readthedocs.io/en/release-1.4/kafka.html
项目源代码
项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp。
Contributor
- Windstamp, https://github.com/windstamp