clfB-tree: Cacheline Friendly Persistent B-tree for NVRAM

2024-04-07 14:58

本文主要是介绍clfB-tree: Cacheline Friendly Persistent B-tree for NVRAM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(一)研究目的

The goal of clfB-tree is to minimize the overhead of failure-atomic update on a B-tree.

(二)研究背景

B-tree 是为易失内存和块设备存储设计的,确保对每个磁盘页进行 tri-atomic(never updated,complete,or unreadable) 写操作,对于这样的块设备存储,使用传统的 shadowing 或是 redo logging 来保证 B-tree 的原子性持久化。
NVRAM 通过 memory bus 而不是 PCI 接口进行访问,且其原子性单元不是 4 KBytes 而是 a cache line,所以 NVRAM 上如何以原子方式更新 B-tree nodes ?

(三)研究概述

clfB-tree 内部节点采用 Differential Encoding,叶节点有两种,一种与内部结点一样采用Differential Encoding,另一种采用 wB+Tree 和 NV-Tree 中的 append-only 策略。
显式地使用限制性事务内存(restricted transactional memory,RTM)实现了 failure-atomic cache line write 函数,并隐式地利用了 write combining store buffer。failure-atomic cache line write 函数有助于最小化 cache line flush 的次数,因此只需要一条 cache line flush 指令就可以更新一个树节点。
clfB-tree 中的 Short-Circuit Shadowing 会导致 upward cascading shadowing problem,为解决此问题,使用 In-Place Update 来自动更新 clfB-tree 节点。

(四)关键技术

clfB-tree

在这里插入图片描述

Differential Encoding in Internal Node

clfB-tree 内部节点的布局如图 1(a) 所示,内部节点的大小设置为 cache line 大小(图中为 64 bytes)。第一个字节标记是叶节点还是内部节点,以及节点中有多少键。第二个字节存储用于编码指针和键的字节数。 第三个字节开始存储第一个 8 字节指针和第一个键,对于其余的指针和键,计算与第一个值的差值。最好情况:指针编码和键编码只需要 1 字节,那么 64 字节的树节点最多有 23 个键和 24 个子指针;最坏情况:指针编码和键编码需要8字节,那么 64 字节的树节点最多有 3 个键和 4 个子指针。

Insertion to Leaf Node

clfB-tree 中设计并实现了两种不同的叶子节点。
第一种:与内部节点一样,称之为编码的叶子,缺点是不能容纳大量的 entries。
第二种:采用 wB+Tree 和 NV-Tree 中的 append-only 策略。插入操作将一个新条目追加到第一个可用的空槽中,一旦新的条目通过 cache line flush 和 store fence 指令安全地写回 NVRAM,就自动地将条目在有效性位图数组中的位设置为 1,并调用另一个 cache line flush 和 store fence 指令。对于删除和更新操作,NV-tree 会附加一个负标志使现有的条目无效,这需要像插入操作一样执行两条刷新缓存行指令。但是 wB+tree 和 clfB-tree 只是通过翻转叶节点位图数组中的有效性位来使现有条目无效。这种 append-only 方法减少了缓存行刷新次数。但是这种方法的一个明显的缺点是键是没有排序的,除非树节点有关于排序的额外信息,否则不能使用二叉搜索。因此,wB+tree 管理两个元数据数组,一个用于有效性的位图数组,另一个用于条目排序的槽数组。在树节点中有两个元数据数组的缺点是它需要额外的缓存行刷新。

FAILURE-ATOMIC CACHE LINE UPDATES

通过使用限制事务内存(Restricted Transactional Memory,RTM)可以实现 failure-atomic cache line write operation。RTM 在 Intel Haswell-EX 架构中是可用的。RTM 提供了三个新的指令——XBEGIN、XEND 和 XABORT,它们允许程序员指定事务的开始和结束,并在事务不能成功执行时显式地中止事务。RTM 最初的设计目的是为多线程应用程序提供硬件事务内存支持。然而,如果 RTM 和写组合存储缓冲区一起使用,我们可以实现 failure-atomic cache line write operation 的预期行为。算法1展示了一个 failure-atomic cache line write 函数的实现。
在这里插入图片描述
在这里插入图片描述
算法 2 展示了使用 atomicCacheLineWrite 能使 clfB-tree 方便地将两个子指针原子地存储在父节点中。为了加强对 clfB-tree 节点的更改的持久性,我们仍然需要调用缓存行刷新和存储栅栏指令,但只调用一次,如图2(a)所示。
在这里插入图片描述

CLFB-TREE UPDATES VIA 8 BYTES ATOMIC WRITES

虽然通过 RTM 和 write combining store buffer 可以实现 failure-atomic cache line write operation,但并不是所有的处理器都支持硬件事务性内存扩展。clfB-tree 使用 shadowingin-place updates 代替 RTM 自动更新树节点。

Short-Circuit Shadowing

Shadowing 是一种 copy-on-write 技术,广泛用于在数据库系统中提供原子性和持久性。Shadowing 复制树节点生成一个副本,然后修改副本,副本持久化则原始节点的父节点通过 8 字节原子写操作更新其指针指向副本。但如果原始节点分裂,则父节点需要同时更新两个指针,这使得 Short-Circuit Shadowing 变得复杂,要自动更新两个指针,需要创建父节点的副本。
在这里插入图片描述
clfB-tree 中的 Short-Circuit Shadowing 需要两个 cache line flush 指令,一个用于 shadow node,一个用于 parent node。shadow node 只需要一个cache line flush 指令的原因是树节点的大小就是 cache line 的大小。
但是 clfB-tree 中的 Short-Circuit Shadowing 会导致 cascading split 问题,因为指向 shadow node 的指针可能比指向原始节点的指针需要更多字节,比如 shadow node 的地址离第一个节点的地址很远,那么 differential encoding 可能需要更多字节,导致父节点中所有指针都必须重新编码并更新整个 cache line。这个问题称为 upward cascading shadowing problem。

In-Place Update

为了解决 upward cascading shadowing problem,使用 In-Place Update 来自动更新 clfB-tree 节点。如算法3所示,In-Place Update 在创建备份副本后对原始树节点进行更改。由于父节点中编码的子节点指针不会更新,除非子节点拆分,否则 In-Place Update 不会出现不必要的 upward cascading shadowing problem,除非叶节点溢出。
在这里插入图片描述
然而 In-Place Update 需要 4 次 cache line flushes。

  • 首先,当一个新条目存储在树节点时,原始树节点的副本被保存为 per-cacheline log。此副本需要1次 cache line flush。
  • 然后,通过将原始节点的有效位设置为 false 来使其无效,这需要另一次 cache line flush。
  • 将有效位设置为 false 后,可以通过多次写操作更新原始树节点。如果系统在此步骤中崩溃,那么可以检查树节点的一致性,并通过检查有效位从故障中恢复过来,并使用保存的 per-cacheline log 覆盖原始树节点。在将所有更改写入原始树节点后,另调用一次 cache line flush 来持久化这些更改。
  • 最后,验证更新后的原始树节点,需要另一次 cache line flush 来翻转有效位。
    在这里插入图片描述

write-atomic B+tree (wB+tree)

write-atomic B+tree (wB+tree) 是 NV-tree 的改进版本,两个都通过 append-only updates 来减少 cache line flashes。
wB+tree的节点需要两个元数据:bitmap array 和 slot array。bitmap array 存储有效条目的位置,slot array 存储条目的排序顺序。wB+tree 的节点结构如图3(a)所示。
在这里插入图片描述
当一个新条目被插入到 wB+tree 节点时,(i)它首先通过在位图中翻转一个位来使槽位数组失效。此步骤需要 clflush 指令。(ii)下一步,它将新条目存储在第一个可用槽中,这需要另一个 clflush 指令。(iii)用更新后的表项顺序更新槽位数组,这一步需要多条 clflush 指令,因为插槽数组的大小可能大于缓存线的大小。(iv)一旦槽位数组被写回 NVRAM,它会用一个 clflush 指令更新位图数组,以标记新的条目和槽位数是有效的。
更新和删除操作类似于插入操作,可以通过更新槽位数组和位图数组来持久化对树节点的更改。对于槽数组和位图数组,wB±tree 每个事务至少需要4次缓存行刷新。
**wB+tree 的一个变体是 slot-only wB+tree(图3b),它在更新响应时间方面优于 bitmap+slot wB+tree,因为它减少了缓存行刷新的次数。**slot-only wB+tree 限制了wB+tree 节点的最大条目数,也就是说,每个树节点存储的条目不超过7个。通过限制条目的数量,wB+tree可以将位图数组和槽位数组结合起来,因为槽位数组可以容纳8个字节,并且槽位数组可以自动更新。通过消除位图数组,只要节点不拆分,slot-only wB+tree 将每次插入的缓存线刷新次数减少到2次。当一个新条目存储在 slot-only wB+tree 节点时,(i)该条目存储在第一个可用槽中,并调用 clflush 指令。(ii)在新的条目被写入NVRAM之后,插槽数组需要通过另一个 clflush 指令进行更新。
当叶子节点溢出时,wB+tree 依赖于 redo-logging,该重写日志调用至少两个缓存行刷新指令,如图4(a)所示。当叶节点拆分时,wB+tree 将溢出的叶节点的一半条目复制到新的右同级节点,并在其父节点中插入指向新同级节点的指针。注意,对父节点的更新和对溢出节点的槽位数组的更新必须同时自动执行。如果系统在更新原始节点的槽位数组之前崩溃,那么原始树节点和新的右兄弟节点可能有多余的条目。为了解决这个问题,wB+tree 使用了 redo-logging,这需要额外的缓存行刷新操作。
在这里插入图片描述
与 wB+tree 不同,clfB-tree 创建两个新的叶节点,并在叶节点溢出时将一半的条目复制到每个节点,如图4(b)所示。在持久化两个新条目之后,在易失性缓存中创建父节点的副本,并将两个指针存储在父节点中。由于父节点可以通过 atomicCacheLineWrite() 或 in-place parent update 自动覆盖现有的父节点,所以只要叶子节点的大小是缓存线大小,clfB-tree 叶子节点的 split 只需要3次 cache line flush 操作。如果一个叶子节点大于缓存线的大小,并且整个叶子节点的更新需要k次cache line flush,那么 clfB-tree 调用 2k + 1 次 cache line flush(1次刷新父节点,2次刷新两个新节点)。在 wB+tree 中,叶子节点拆分需要 2k + 4 次缓存行刷新(2次用于溢出节点的原地更新,k次用于重做日志记录,k次用于右兄弟节点,另外2次用于父节点更新)。

(五)实验

用C语言实现了clfB-tree、slot-only wB-tree 和 CDDS B-tree,与一个 NVRAM 堆管理器 Heapo 集成在一起,并进行实验比较。没有评估 NVtree 和 FP-tree,因为它们不能保证内部树节点的故障原子性。它们不是持久索引,因为当系统故障时,它们需要从叶子节点重建整个树结构。我们将这三个持久b树与一个NVRAM堆管理器—heapo[8]集成在一起。
实验平台:
一个平台是拥有一个 Intel Xeon E7-4809 v3 处理器(2.00GHz, 8 × 32KB指令缓存,8 × 3 2 KB 数据缓存,8 × 256KBytes L2 caches,,20MBytes L3 cache) 和 64GB DDR3 DRAM 的工作站。Xeon E7-4809 v3 处理器支持 TSX (Transactional Synchronization Extensions) 包括 RTM 功能。在这个平台中,假设 NVRAM 和 DRAM 一样快,并且 DRAM 的特定地址范围是 NVRAM。
另一个平台是一个 NVRAM 仿真板–Tuna,拥有 ARM Cortex-A9 处理器, Xilinx Zynq XC7Z020 ARM-FPGA SoC, 以及可以控制两个 DRAM 中的一个的读/写延迟来模拟 NVRAM 延迟的 FPGA 可编程逻辑。

(六)总结

实验结果表明,clfB-tree 在插入和搜索性能上优于 slot-only wB-tree。

这篇关于clfB-tree: Cacheline Friendly Persistent B-tree for NVRAM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/882916

相关文章

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

iptables持久化命令:netfilter-persistent save

在Linux上,使用netfilter-persistent命令可以保存iptables防火墙规则,确保它们在系统重启后仍然有效。以下是如何使用netfilter-persistent来保存iptables规则的步骤: 打开终端:首先,你需要打开Linux系统的终端。保存规则:使用netfilter-persistent save命令可以保存当前的iptables规则。这个命令会调用所有插件,将

Sorry!Hbase的LSM Tree就是可以为所欲为!

我们先抛出一个问题: LSM树是HBase里使用的非常有创意的一种数据结构。在有代表性的关系型数据库如MySQL、SQL Server、Oracle中,数据存储与索引的基本结构就是我们耳熟能详的B树和B+树。而在一些主流的NoSQL数据库如HBase、Cassandra、LevelDB、RocksDB中,则是使用日志结构合并树(Log-structured Merge Tree,LSM Tr

【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid

spring-in-action-6-samples 的JDK版本 最小是11,我使用 了22: jdk21 jdk22 都与lombok 不兼容,必须使用兼容版本, 否则报错: thingsboard 的大神解释了: java: java.lang.NoSuchFieldError: Class com

[LeetCode] 863. All Nodes Distance K in Binary Tree

题:https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/ 题目大意 求给树中,距给定 结点 指定长度的 所有结点的val 思路 tree -> graph 、 bfs 先遍历树,并用map记录每个结点的父结点 ,将树变为图,然后 bfs。 /*** Definition for a binary tree

js实现树级递归,通过js生成tree树形菜单(递归算法)

1、效果图 需求:首先这是一个数据集—js的类型,我们需要把生成一个tree形式的对象 : var data = [{ id: 1, name: "办公管理", pid: 0 },{ id: 2, name: "请假申请", pid: 1 },{ id: 3, name: "出差申请", pid: 1 },{ id: 4, name: "请假记录", pid: 2 },{ id:

【unity实战】利用Root Motion+Blend Tree+Input System+Cinemachine制作一个简单的角色控制器

文章目录 前言动画设置Blend Tree配置角色添加刚体和碰撞体代码控制人物移动那么我们接下来调整一下相机的视角效果参考完结 前言 Input System知识参考: 【推荐100个unity插件之18】Unity 新版输入系统Input System的使用,看这篇就够了 Cinemachine虚拟相机知识参考: 【推荐100个unity插件之10】Unity最全的最详细的C

树链剖分 + 后缀数组 - E. Misha and LCP on Tree

E. Misha and LCP on Tree  Problem's Link   Mean:  给出一棵树,每个结点上有一个字母。每个询问给出两个路径,问这两个路径的串的最长公共前缀。 analyse: 做法:树链剖分+后缀数组. 记录每条链的串,正反都需要标记,组成一个长串. 然后记录每条链对应的串在大串中的位置,对大串求后缀数组,最后询问就是在一些链

数据结构 - Codeforces Round #353 (Div. 2) D. Tree Construction

Tree Construction  Problem's Link  ---------------------------------------------------------------------------- Mean:  给定n个数,按照构造Binary Search Tree的方式来构造BST树,按顺序输出每一个非root结点的父节点的值。 analyse