软硬件结合,分布式数据库 ZNBase 存储架构优化实践

ZNBase 是开放原子开源基金会旗下的首个分布式数据库项目,由浪潮大数据团队开源并捐赠。本文将介绍 ZNBase 的存储架构,以及 ZNBase 技术团队在其 KV 存储引擎基础上所作的优化实践。git

ZNBase 总体存储架构

云溪数据库 ZNBase 采用分层架构,分为计算层与存储层,其整体架构以下图所示:算法

在 OLTP 场景下,当开发人员向集群发送 SQL 语句时,数据最终会以键值对 KV 的形式对存储层进行读写。每一个 ZNBase 节点启动时,至少会包含一个存储节点。存储层默认采用 KV 存储引擎 RocksDB 负责存储数据。每一个存储实例均可能包含多个 Range,Range 是最底层的 KV 数据单元。Range 使用 Raft 一致性协议在集群间进行复制。数据库

为了支持 HTAP 场景,ZNBase 的行存数据会经过 Raft Learner 同步到列存引擎,存储层还扩展了矢量接口,经过列式存储、计算下推、多节点并行计算知足业务应用的 AP 需求。另外存储层还扩展了时序接口,能够进行时序数据管理。缓存

接下来将着重介绍 ZNBase 存储层架构中的 KV 存储集群。安全

RocksDB 引擎

ZNBase 的存储层默认采用 RocksDB 来存储数据。RocksDB 是由 Facebook 开源的高性能 KV 存储引擎,读写数据能够是任意字节流,其官方架构如图所示,是一种 LSM-Tree 的实现:网络

 RocksDB 写入流程以下:架构

一、以 batch 形式先顺序写入 WAL 文件用于故障恢复异步

二、再写入内存中的 Memtable,Memtable 默认以 SkipList 形式存储分布式

三、Memtable 写满必定大小,默认 64MB,会转为不可变的 Immutable。工具

四、异步线程会将 Immutable 刷到磁盘 L0 层,变为 SST 文件。

五、磁盘中使用多层来管理 SST 文件,经过合并过程将上层的 SST 文件落到下层,在合并过程当中会进行 GC 清理。

因而可知,RokcsDB 最新的数据是在内存或者上层的 SST 文件里,因此读取时优先读取 Memtable 和 Immutable,再依此读取各层文件。刚写入的热数据,能够更快被读到。另外 RocksDB 还提供了 Block Cache 进行读缓存。 

RocksDB 自己是一个 LSM-Tree 架构的高速 KV 存储引擎,读写都会尽可能使用内存。RocksDB 提供原子的批量写入、快照等功能,方便上层实现事务控制。基于 RocksDB 也支持高度安全的 AES 算法对存储在磁盘上的数据加密,这样即便磁盘被窃取,磁盘里的数据也没法被访问。

因为 RocksDB 采用 LSM-Tree 架构,一样也存在必定的问题。好比在大数据量下有比较高的读放大、写放大、空间放大,性能衰减也比较厉害。为了提升 ZNBase 在海量数据下的性能表现,ZNBase 团队结合浪潮的硬件优点,开发了使用 SPDK 驱动在专用硬件 ZNS SSD 上进行软硬件融合的存储引擎;另外为了更有效的利用内存,得到更快的读写速度,在大内存场景下也开发了准内存引擎的实现

SPDK + ZNS SSD

固态硬盘(SSD)正在迅速扩展它在数据中心中的份额,相较于传统存储介质,新的闪存介质具备性能,耗电,机架空间等等方面的优点。

而浪潮自研的 ZNS SSD,在容量、寿命、成本、易用性、性能等方面实现飞跃式提高。ZNS SSD 即分区命名空间固态硬盘,能够将 FTL(Flash Translation Layer)暴露给用户以充分发挥 SSD 性能。ZNS 技术针对云场景应用,主适用于大容量空间存储的数据,例如高清视频、图像等。ZNBase 与 ZNS SSD 集成,经过智能数据部署能够实现更好的空间运⽤,得到下降一倍以上的写放大;文件可根据生命周期进行数据分区隔离,实现最低化垃圾回收;SST 文件可根据 LSM 分层进行清晰化冷热数据分离,提高访问效率;最小化的写放大可提高读取性能,减小合并成本和垃圾回收开销;理论上,ZNS SSD 可带来 15% 的性能提高和 10% 的成本收益

 

因为 SSD 自己的物理特性,其数据的访问相较于传统介质来讲已经很是快了,而性能的瓶颈就是出在计算机与设备链接的接口和协议上面。举个直观的例子,咱们从北京乘飞机到美国,按照如今的飞行速度,在天上须要 13 个小时。这种状况下,安检的时间,过海关的时间,候机的时间,加起来 3 个小时,相对于总共的 13+3=16 个小时也不算长。设想若是如今飞机的飞行速度提升了 100 倍,飞行时间从 13 小时缩短至 10 分钟,这时 3 个小时的地面手续流程就显得很没有效率了。换言之,在存储硬件性能高速发展的今天,存储软件协议栈的性能和效率在存储总体系统中的地位愈来愈重要。

SPDK ( Storage performance development kit ) 由 Intel 发起,提供了一组用于编写高性能、可伸缩、用户态存储应用程序的工具和库。SPDK 的基础是用户态、轮询、异步、无锁 NVMe 驱动,提供了从用户空间应用程序到 NVMe 设备的零拷贝、高度并行的访问。

NVMe 的全称是 Non-Volatile Memory Express,若是翻译过来就是非易失性内存主机控制器接口规范,是一种新型的存储设备接口规范,用于定义硬件接口和传输协议,拥有比传统 SATA SSD 的 AHCI 标准更高的读写性能。咱们能够把 NVMe 看作一个硬件进步推进软件革新需求的例子,随着后续更快的存储介质投入市场,这种推进力将更为急迫。 

SPDK 项目也是一种硬件进步推进软件革新的产物,其目标就是可以把硬件平台的计算、网络、存储的最新性能进展充分发挥出来。那么 SPDK 是如何工做的?它超高的性能实际上来自于两项核心技术:第一个是用户态运行,第二个是轮询模式驱动

首先,将设备驱动代码运行在用户态,是和运行在“内核态”相对而言的。把设备驱动移出内核空间避免了内核上下文切换与中断处理,从而节省了大量的 CPU 负担,容许更多的指令周期用在实际处理数据存储的工做上。不管存储算法复杂仍是简单,也不管进行去重(deduplication),加密(encryption),压缩(compression),仍是简单的块读写,更少的指令周期浪费意味着更好的总体性能。

其次,传统的中断式 IO 处理模式,采用的是被动的派发式工做,有 IO 须要处理时就请求一个中断,CPU 收到中断后才进行资源调度来处理 IO。举一个出租车的例子作类比,传统磁盘设备的 IO 任务就像出租车乘客,CPU 资源被调度用来处理 IO 中断就像出租车。当磁盘速度远慢于CPU 时,CPU 中断处理资源充沛,中断机制是能对这些 IO 任务应对自如的。这就比如是非高峰时段,出租车供大于求,路上老是有空车在扫马路,乘客随时都能叫到车。然而,在高峰时段,好比周五傍晚在闹市区叫车(不用滴滴或者专车),经常是看到一辆车溜溜的近前来,然后却发现后座已经有乘客了。须要等待多久,每每是不可预知的。相信你必定见过在路边滞留,招手拦车的人群。一样,当硬盘速度上千倍的提升后,将随之产生大量 IO 中断,Linux 内核的中断驱动式 IO 处理(Interrupt Driven IO Process)就显得效率不高了。

而在轮询模式驱动下,数据包和块获得迅速派发,等待时间最小化,从而达到低延时、更一致的延时(抖动变少)、更好的吞吐量的效果。

固然,轮询模式驱动并非在全部的状况下都是最高效的 IO 处理方式。对于低速的 SATA HDD,PMD 的处理机制不但给 IO 性能带来的提高不明显,反而浪费了 CPU 资源。

准内存引擎

除了采用 SPDK+ZNSSD 软硬件结合的存储引擎之外,为了更有效的利用内存,得到更快的读写速度,ZNBase 在大内存场景下还开发了准内存引擎的实现。

准内存引擎开发的背景源自 RocksDB 的一些局限性:

1.WAL 的单线程写模式,不能充分发挥高速设备的性能优点; 

2.读操做时,有可能须要查找 level 0 层的多个文件及其余层的文件,这也形成了很大的读放大。尤为是当纯随机写入后,读几乎是要查询 level0 层的全部文件,致使了读操做的低效。

3.针对第 2 点问题,RocksDB 中依据 level 0 层文件的个数来作前台写流控及后台合并触发,以此来平衡读写的性能。这又致使了性能抖动及不能发挥高速介质性能的问题。 

4.合并流程难以控制,容易形成性能抖动及写放大。

近年来,随着动态随机存储器(DRAM)容量的上升和单位价格的降低,使大量数据在内存中的存储和处理成为可能。相对于磁盘,内存的数据读写速度要高出几个数量级,将数据保存在内存中相比从磁盘上访问可以极大地提升应用的性能。

针对这一理念,准内存引擎设计原则以下:

1.数据尽可能存放在内存中,充分利用内存的读写性能。

2.基于索引与数据分离存储的思想,索引常驻内存。数据能够根据内存容量,将部分存储到持久化存储设备中。

3.提高 cpu cache 命中率,经过数据块的重构(拆解、扩容、缩容)将 Key 相邻的 KV 数据在内存空间中也相邻,以提高 key 值遍历的速度。

4.使用异步落盘机制,保证平滑的 IO 速率,消除 IO 瓶颈。

基于 ART 索引的检索机制,保证数据访问速度。ART 算法使用基于乐观锁的的同步机制,读操做不阻塞,写操做使用版本信息的 CAS 原子操做以及重试机制。

因为已经过 Raft Log 实现数据的故障恢复,能够去除 WAL 写入过程。

 

准内存引擎整体处理流程以下:

1. 新插入的数据存放在 内存临时区中的 Memtable 以及 Immutable 中。

2. 异步线程 Mem-Flush 将 Immutable 中的数据转存到内存存储区。

3. 内存存储区会尽量占用更多的内存空间,用于存放数据。使用 ART 算法索引这些数据。

4. 内存存储区内存空间即将不足时,启用 L1-Flush 后台线程清理内存存储区中的数据。

5. L1-Flush 后台线程,将该内存存储区中全部的 KV 数据以及范围删除数据进行落盘。因为数据量大且数据有序,所以,直接落盘到 L1 层。落盘前须要保证 L1 层无文件。落盘完成后,建立 L1 层文件向下合并的任务。

准内存引擎采用 ART 算法做为主索引的实现,能够进行快速的范围查找,辅助使用 Hash 索引方便进行 Get 查询。之因此使用 ART 算法,是由于其在读写方面性能均优于 B+树、红黑树、二叉树,可比肩哈希表,而 ART 算法比哈希表的优点是 ART 算法可按顺序遍历全部数据。

参见论文:The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases

总结

本文为你们介绍了 ZNBase 基于 RocksDB 的存储引擎架构,以及 ZNBase 团队针对 RocksDB 的局限性,经过开发软硬件结合的 SPDK+ZNS SSD 存储引擎、大内存场景下的准内存引擎,大大提升了存储引擎的读写性能。


关于 ZNBase 的更多详情能够查看:

官方代码仓库:https://gitee.com/ZNBase/zn-kvs

ZNBase 官网:http://www.znbase.com/ 

对相关技术或产品有任何问题欢迎提 issue 或在社区中留言讨论。同时欢迎广大对分布式数据库感兴趣的开发者共同参与 ZNBase 项目的建设。

联系邮箱:haojingyi@inspur.com

相关文章
相关标签/搜索