热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ForkBase:AnEfficientStorageEngineforBlockchainandForkableApplications

ForkBase:AnEfficientStorageEngineforBlockchainandForkableApplications,Go语言社区,Golang程序员人脉社

ForkBase是一种数据存储系统,旨在支持需要数据版本控制、分叉和防篡改等功能的应用。一个主要的例子就是区块链系统,但这还可能包括协作应用,比如GoogleDocs。举例说,如今以太坊和HyperLedger的数据结构就直接建立在键值存储系统上。ForkBase力求改而将上述这些属性一路推送到存储层:

一个直接的好处是,它为需要任意组合的上述功能的应用减少了开发工作。另一个好处是,它提供了额外的功能(比如高效的历史查询),根本无需额外成本,帮助应用更好地普及开来。最后,该存储引擎可以利用在应用层很难实现的性能优化。

实际上我们最终得到的是一种建立在底层对象存储系统上的键值存储系统,直接支持版本控制、分叉和篡改证据。ForkBase的核心是一种新颖的索引结构,名为POS-Tree(面向模式的拆分树)。

ForkBase架构

从下往上,ForkBase包括块存储层、表示层和一套数据访问API,块存储层执行分块和重复数据删除,表示层管理版本、分支和防篡改,这套API结合了结构化数据类型和分叉语义。更高级的应用服务(比如访问控制和自定义合并函数)可以实施在API的上面。

ForkBase是一种键值存储系统,其中存储的对象是FObject的实例。

数据版本控制

数据版本控制(保留每一个数据项的完整历史记录,包括任何分支和合并)方面的主要挑战是,管理存储的使用。很显然,重复数据删除大有机会,假设一个版本的内容与下一个版本并不完全改变。

基于增量数据(delta)的重复数据删除功能仅存储版本之间有差异的数据(delta),并通过遵循增量数据链来重构某个特定版本。在这种场景下,你可以尝试调整存储/重构成本取舍。

基于内容的重复数据删除将数据拆分成块,每个块都由其内容(即内容的哈希)作为独特的标识。然后可以检测到同样的数据块,消除冗余副本。

ForkBase选择了在块级进行基于内容的重复数据删除。与文件系统中使用的类似技术相比,ForkBase使用更小的块和可感知数据结构的分块策略。比如说,一个列表只会在元素边界处被拆分,那样根本不需要用多个块来重构列表项。ForkBase可识别许多不同类型的块,每种类型的块都由cid作为独特的标识,cid就是块内容的哈希。

可分块的对象类型(Blob、List、Set和Map)以POS树的形式存储起来。

FObject的uid只是该对象的Meta块的块id的别名。

分叉语义

对分叉的支持基于两个关键操作:分叉和冲突解决。分叉操作创建一个新的分支,分支与其他分支隔离开来的本地修改互相独立发展。ForkBase支持按需求分叉和按冲突分叉。

通过API显式请求按需求分叉,用用户提供的名称加以标记。一旦并发修改同一个数据项,隐式创建按冲突分叉。因Fork-on-Conflict而创建的分支是未标记的,就由其uid来标识。

标记的分支可以与另一个分支合并,由标记或版本作为标识。合并期间检测到冲突时,将返回冲突列表,并要求应用层提供解决方案。有内置的解析函数适用于简单的策略,比如追加、聚合和选择一个。

篡改证据

FObject的uid是对象的值及其衍生历史的独特标识。因此,逻辑对等要求对象不仅有同样的值,还有同样的历史记录。诸版本用加密哈希链连接起来,确保能够检测到企图篡改的任何行为。每个FObject存储它从bases字段获得的之前版本的哈希。

面向模式的拆分树

大型结构化对象通常不会全部访问。相反,它们需要细粒度的访问,比如元素查找、范围查询和更新。这些访问模式需要索引结构(比如B+-tree)很高效。但是现有的索引结构并不适合有许多版本,且版本可以合并的环境。

B+-trees和变体的基于容量的拆分策略对索引的值及其插入顺序非常敏感。这样一来,更难跨版本进行重复数据删除,合并两个版本时也更难发现之间的差异。使用固定大小的节点可以避开插入顺序问题,但由于结构中间的插入,带来了另一个问题:边界移位问题。

研究人员的解决办法就是使用面向模式的拆分树,它支持下列属性:

  • 快速查找和更新
  • 快速确定两棵树之间的差异,然后合并
  • 高效的重复数据删除
  • 篡改证据

树中的每个节点都是一个块(索引块或树叶处的对象块)。查找遵循拆分键指引的一条路径。子节点的cid是其内容的密码哈希,就如默克尔树(Merkle tree)中那样。拥有同样数据的两个对象将有同样的POS树,树比较提供了一种高效的递归解决方案。这里真正的秘诀在于,POS树如何决定在哪里拆分。

其结构受到基于内容的分片的启发,酷似B+-tree和默克尔树的组合。在POS树中,节点(即块)边界被定义为通过对象内容来检测的模式。具体来说,想构建一个节点,我们会从头开始扫描,直到一个预定义模式出现,然后创建新节点来保存扫描的内容。由于叶节点和内部节点的随机性程度不一样,我们为它们定义了不同的模式。

叶节点拆分使用滚动哈希函数来完成。只要滚动哈希中的q最低有效位都是零,模式匹配就会发生。如果模式匹配发生在元素的中间(比如Map的键值对),就会扩展块边界以覆盖整个元素。因此,除最后一个节点以外的每个叶节点都以一个模式结束。

索引拆分使用一种更简单的策略,寻找cid && (2^r -1) == 0的cid模式。可以通过为q和r选择适当的值来配置期望的块大小。为了确保块不会随意增大,可以强迫块处于某个阈值。POS树不是为对象内容仅仅是重复项的序列这种情况设计的――没有模式,所有节点都倾向于最大块大小,边界移位问题又回来了。

ForkBase实战:Hyperledger

论文的第5部分介绍了在ForkBase上构建区块链平台、维基引擎和协作分析应用程序。我在这里只想侧重于区块链使用场合,研究人员将Hyperledger v0.6移植到ForkBase的上面。

将Hyperledger移到ForkBase上只需要18行新的代码,并且从Hyperledger代码库删除1918行代码。(请注意,ForkBase本身大约有3万行代码!)。

另一个好处是,数据现在随时可用于分析。如果是状态扫描查询,我们只要关注存储在最新块中的版本号,即可获得所请求的键的最新Blob对象。之后,我们关注base_version来检索以前的值。如果是块扫描查询,我们关注存储在请求块上的版本号来检索此块的二级Map对象。然后,我们遍历键值元组,并检索相应的Blob对象。

状态扫描(返回特定状态的历史记录)和块扫描(返回特定块的状态值)在最初的Hyperledger代码库中比较慢,该代码库是为快速访问最新状态而设计的。(注意:这似乎要引用HyperLedger的对等事务管理器即PTM组件。Hyperledger还包含被索引的块存储系统)。

在这些扫描操作中,ForkBase显示出最大的性能优势。如果我们考虑延迟和吞吐量,基于ForkBase的Hyperledger实现和基于Rocksdb的Hyperledger实现非常接近。(下图中的ForkBase-KV是Hyperledger使用ForkBase作为纯粹的键值存储系统,并没有充分利用任何高级功能)。


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
author-avatar
手机用户2602900871
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有