OPED 是 (我自己发起的) One Paper Each Day 挑战, 即每天(偶尔)读一篇 Paper, 领域不限.

这是 OPED 挑战的第九篇, 论文为 Lockless Transaction Isolation in Hyperledger Fabric

这篇论文很简单, 我花了半个小时就读完了, 个人感觉收获不大.

Hyperledger Fabric

先讲讲 Hyperledger 是什么. 它是一个 Linux Foundation 下开源的区块链项目, 而 Hyperledger Fabric 是这个项目中的 Go 实现的分布式 Ledger. 我对区块链不是特别了解, 所以不太清楚这个项目和以太坊之类的有什么区别. 这篇论文讲的内容也和区块链关系不大.

问题

区块链有一个已知的问题, 就是吞吐量不行, 比如比特币转账需要过好久才能确认, 这是比特币本身的设计导致的. 在比特币中, 一个 transaction 要被包括到一个 block 并加到链上, 并且要求这条链够长, 才算是确认了这次交易. 这实际上可以理解成排序的过程, 只不过在比特币场景下, 每个人都可以试着排序, 但是最后只有一个大家都同意的排序能够胜出. 很明显, 这样的设计下, 一个事务从发起到确认, 需要很久. 并且, 这个共同排序的过程实际上等效于只有一个人做了有意义的工作 (挖上了矿), 其他人都再做无用功. 比特币这样的设计还有一个副产品, 就是事实上给 transactions 赋予了全序关系, 即使两个事务好不相关.

这篇论文把这种类型的事务执行方法叫做 order-execute architecture, 意思就是需要先要取得一致的排序, 然后再执行.

Execute-Order-Validate

为了解决上面的问题, HyperLedger 实现了另一种架构 Execute-Order-Validate. 在这种架构下, 会有这么几种组件:

  1. Client: 用户, 事务的发起方
  2. Endorsing Peers: HyperLedger 中实际维护账本的人, 它使用 KV 存储来保存状态
  3. Ordering Service: 为事务排序的服务

事务执行的流程是:

  1. Client 发送事务数据给所有 Endorsing Peers.
  2. 每个 Peer 在本地模拟执行事务, 计算这个事务的 readSet, writeSet. 注意这里的执行只是计算事务会带来的改动, 并不会修改状态.
  3. Peer 将自己计算出的改动发送给 Client.
  4. Client 收到所有的改动之后, 将事务及改动发给 Ordering Service.
  5. Ordering Service 会定期将收到的事务打包成 block 发送给所有的 peer.
  6. Peer 收到的 block 之后会验证 block 中的事务, 如果合法就提交到本地状态.

为了保证隔离性, HyperLedger 在步骤 2 会上读锁, 在步骤 6 会上全局写锁.

这种架构相比于 Order-Execute 的好处是, 事务的执行被分散在了不同的 peer 上 (不同的事务可以有不同的 endorsing peers 集合?). 然而, 步骤 6 的写锁还是会成为瓶颈.

Lockless Transaction

实际上 HyperLedger 就是加了个一个简单的小 trick, 就是在步骤 2 开始的时候, 先获取当前状态的版本号. 然后在本地模拟执行事务的过程中, 如果读到任何一个值的版本号更新, 就会 abort. 这实际上是一个很简单的思路, 就是保证在事务执行过程中, 读的字段没有被修改, 如果修改就提前停止.

总结

我个人感觉这篇论文的信息量不大, 主要说的就是执行前获取版本号来做 conflict detection. 这种做法和 MVCC 很像, 很多项目都有使用类似的思路, 比如 Omid.