【存储专栏】打破K/V存储的性能瓶颈

本文探讨了区块链存储模块的数据库选型与优化,重点关注账本数据和索引数据的存储挑战。针对区块链账本的存储,文章分析了状态数据的存储需求,指出基于LSM-tree的存储引擎如Leveldb的局限性,并提出了通过修改集和预写日志(WAL)优化回滚效率的方案。在索引数据方面,以以太坊和Hyperledger Fabric为例,分析了数据结构和性能问题,并提出通过调整键的顺序性以优化LSM-tree的性能和减少归并操作。文章最后总结了区块链数据库性能优化的重要性,并展望了未来可能的解决方案。
摘要由CSDN通过智能技术生成

【前言】
前文《区块链 ≠ 分布式存储》中,介绍了「区块链系统」和「传统分布式数据库」的异同,并认为“世界状态”的维护是区块链系统或区块链存储模块的核心关注点,而交易数据、账户及其相关数据、交易执行结果三者一同构成账户模型下区块链系统最基本的世界状态。

本文将从数据特点、性能表现、扩展性等方面出发,对区块链存储模块的数据库选型及定向优化进行介绍。
在这里插入图片描述
区块链存储模块需要关心的数据类型

【账本数据】
▲ 什么是区块链账本?
通常情况下,区块链账本包含「账户数据」与「合约数据」。
用一个日常的例子来理解账本:在查询银行账户时,我们最关注的可能是当前的余额,但如果要探究当前的余额是经历怎样的变化而来,就需要去查询历史的交易记录。这就体现出了区块链账本的核心含义,即当前的状态(余额)与一组决定该状态的交易,如下图所示:
在这里插入图片描述
在区块链中,上述状态代表系统中所有对象的当前状态集合,其往往是一个哈希值,而且当任意一个对象发生改变,该哈希值就会彻底改变。借助该哈希值,我们能非常直观的判断两个区块链节点是否处于相同的状态;而决定状态的交易指的其实就是物理上的区块链,链上存储了所有造成状态改变的交易,不同于世界状态,区块链只能追加而不能被修改。

▲ 如何存储账本?

如果从「数据类型」的角度出发,经过上面的分析我们其实可以看出区块数据其实是一种连续的且只支持末尾追加的结构,因此完全可以充分利用磁盘顺序写入的优势,连续地进行存储(本系列的后续文章将着重介绍:区块链连续型数据的存储);而对于「状态数据」来说,由于会被频繁地写入和更新,因此从性能角度出发,状态数据更适合基于LSM-tree的存储引擎,如以太坊[1]、Hyperledger Fabric[2]等区块链项目均使用Leveldb作为默认的状态数据库。

区块链需要保证每一笔交易执行的原子性:一笔交易要么完全执行成功,要么完全执行失败,一旦执行过程中产生了错误,就需要回退掉这笔交易带来的所有状态修改。

以太坊引入了StateDB的概念来解决这个问题,即把某一笔交易执行过程中产生的修改缓存在内存数据库中,执行成功后再借助Leveldb原子写入的特性进行持久化。

▲ 问题分析

在区块链正常运行的情况下,上述对于账本的存储方式没有任何问题。然而我们知道,在以比特币[3]、以太坊为代表的公链中,出现短暂的链分叉是非常普遍的现象(如下图所示),节点可以根据预设的协议(如比特币的最长链原则)进行自动恢复;而即使在使用了拜占庭容错类算法的联盟链中,在算法层面不可能发生分叉,但仍然可能出现某个节点因为写入过程宕机、拜占庭行为、系统资源或硬件故障等原因造成执行失败或数据不一致的问题,从而也产生了分叉的现象,为了保证系统的鲁棒性和逻辑的完备性,在联盟链中也需要对分叉的状态进行数据恢复的机制。
下图表示整个区块链处于分叉的状态,五角星区块代表了上一次全网一致的状态,正三角形和倒三角形分别表示了当前两个不同的状态。
在这里插入图片描述

经过上面的介绍,我们若要进行数据的恢复,让整个系统恢复一致,需要那些异常节点:

1)回滚掉分叉点之后的区块和交易;

2)撤回这些交易对状态数据库造成的影响。

前者的实现可以非常简单,若我们通过KV数据库来存储区块和交易数据,那么我们可以根据对应区块号或者交易哈希来进行删除操作&

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值