本文从分布式系统角度讨论了区块链中的几种创新模式:不可变模式、异步和共识以及网络容错可靠性。
不可变模式
区块链是不可变的。 分布式系统已经在相当一段时间内依靠不变性来消除异常。 比如日志结构的文件系统、日志结构的合并树和Copy-On-Write(写时复制)是分布式系统中用于模拟不可变数据结构的常见模式/技巧。 区块链以类似于事件溯源Event Sourcing的方式来处理事务,这是分布式计算中用于处理事实和操作的常用技术。 不是用最新数据覆盖旧数据,而是创建一个包含所有事件/行动的只能不断追加append-only的日志。
帕特·赫兰德(Pat Helland)在他重要的流行论文“不变性改变一切 ”中描述了不变性:
会计师不能使用橡皮擦; 否则他们旧可能蹲监狱。 分类流水账中的所有条目都保留。 可以进行更正,但只能在分类帐中新增要进行更正的条目。 正如当公司的季度业绩公布时,会包括上一季度的小幅修正,这种小修正是属于追加性质的,因为上一季度的数据已经公布,无法改变,只能在本季度进行数据修正,这种修正从时间角度看实际是新增追加。
区块链是简单的分布式会计分类帐,因此名称称为Distributed Ledger Technology(分布式分类帐技术),简称DLT。
异步
区块链可能运行在距离数千英里的各种服务器上。 在这种异步网络中想保证各种订单交易的前后顺序性是分布式系统经典问题。 所有不可能的理论如像FLP定理(分布式系统的共识(consensus)算法)和CAP定理都适用于区块链。
如同分布式系统一样,区块链块中没有“现在”概念 ,分布式系统中的不同节点的时钟可能会相互隔离,因此,在全局所有机器上的对事件进行全局性的实时排序并不简单,因为所有节点时钟不能始终处于同步之中,因此使用机器本地时间戳将不再有帮助,除此之外,消息的延迟可以达到任意时间,可以是毫秒或秒级,甚至达到分钟甚至几天的数量级,对于比特币区块链,创始人中本聪设计了一种巧妙的方式来排序订单交易,以防止双重支出的问题,在没有全局时钟情况下使用了分布式Timestamp服务器 。中本聪的比特币白皮书中说:
我们的解决方案是基于时间戳服务器,时间戳服务器的工作就是通过获取要被时间戳标识的某个区块的条目的哈希值,然后广泛发布这个哈希值,例如在报纸或BBS帖子中,总是附加具体的发布时间,这个时间戳提供了当时数据(新闻或帖子)存在的证明。 每个当前时间戳包含之前的时间戳哈希,由此形成一个链条,这样一个时间戳相当于有两份存在证明,更加坚固可靠。
这类似于DBMS(数据库管理系统)中通过事务日志记录保存所有对数据库的写入操作事件。 在这种情况下,区块链本质上是一个分布式事务日志 。
共识
在没有全局同步时钟的情况下,决定订单交易顺序的唯一方法是通过分布式共识。 就像在分布式机器上对事件/事务进行排序达成共识一样,但是在分布式系统中达成共识很困难:
FLP(不可能的结果)表明,在异步网络中,消息可能被延迟但不会丢失,如果至少有一个节点发生故障停机了,那么就不可能达到所有机器获得共识一致。
能够对网络的崩溃故障进行容错的算法有:Paxos , Zab , Raft , Viewstamped复制,这些网络容错算法能够在流程或机器可能发生崩溃或导致消息传递延迟的情况下达成共识一致性。上述算法通常在一个可控的组织内实现分布式系统。
区块链工作在更加复杂的条件下,用来处理称为“拜占庭将军问题”的故障类型 ,其中一些节点可能是恶意的,因为节点是由不相互信任的不同实体/组织运行。 区块链假设是你自己的网络并不在你身边。 因此,您需要拜占庭容错算法才能在区块链中达成共识。 拜占庭容错算法已经在分布式系统文献中存在很长期的研究了。 1999年,Miguel Castro和Barbara Liskov介绍了实际拜占庭容错 (PBFT)算法,该算法提供了高性能拜占庭状态机复制,每秒处理数千个请求,延迟时间为毫秒级。 虽然这篇文章是在1999年写就的,但是直到比特币在2008年使用“工作证明”算法,还没有其他BFT算法的已知实践实现,只是在一些系统中用来限制垃圾电子邮件。 区块链引起了对BFT算法重新研究的兴趣,并在学术界积极努力下催生了大量新的BFT算法,一些应用案例包括 Proof Of Stake, Bitcoin-NG, Tendermint 和 Honey Badger.。
网络可靠性
与普通人大众想法不同的是:网络默认是不可靠 。 分布式系统工程师必须处理这个冷酷事实。 比特币和其他加密货币被建立在互联网上工作,其中网络分区和消息丢失/重新排序是常见的。 有趣的是,区块链数据结构本身是检测消息丢失和重新排序的一种聪明的方法。 每个块都有一个指向前一个块的指针,类似于一个链表,可以很容易地检测到丢失的块(块链接中的“孤立块”)。 再次引用中本聪语录:
新的交易不一定需要广播到达所有节点。 只要能到达大多数节点即可,这些新交易很快进入一个区块中。堵塞广播也能容忍消息的丢弃。 如果一个节点没有收到一个块,它会在接收到下一个块时,如果意识到那块被忽略了就会重新请求它。
这个原理类似于复制交易日志或日志传送,这是用于保持副本(特别是只读副本)同步的常用技术。 当一个交易日志被订阅关注时,就会提供了一个简单的机制来检测差距和修复副本。 类似地,可以通过检查区块中的merkle根(代表区块中所有交易的哈希)来验证块链中每个块的完整性。 因此,很容易发现缺少的交易。提醒一下,merkle树是在复制同步技术anti-entropy中非常常用的技术。
区块链是一个令人兴奋的技术突破。 让我们首次拥有一个在不相互信任的实体之间实现的分布式数据库。 我们还处在这个有趣技术的早期阶段,类似于当初编写第一个分布式的NoSQL数据库,如亚马逊的Dynamo或Google的BigTable时期。 这些分布式数据库为我们展示了构建大型数据库的新途径,并且开辟了新的设计模式和数据结构。 NoSQL数据库现在已经被商品化了。 如果您听到有关新的NoSQL数据库,90%的模式和算法是一样的。 DLT也正在经历类似的阶段,最终将成为商品化。 但是现在还是早期阶段,我们正在挖掘建立它们的最佳模式。