NVM 作为主存上对数据库管理系统的影响
implications of non-volatile memory as primary storage for database management systems
摘要
传统的数据库管理系统使用磁盘存储关系型数据。硬盘的特点:廉价、持久性、大容量。然而,从磁盘进行读取数据代价非常高。为了消除这个延迟,需要DRAM 作为中间媒介。 DRAM 的特点:比磁盘速度快,但容量小且不具备持久性。 NVM 是一个新兴的存储技术,具有容量大、字节寻址、堪比 DRAM 的存储速度、非易失兴。
本文,我们综述了NVM 作为主存对关系型数据库管理系统的影响。即,研究了如何修改传统的关系型数据库管理系统以充分利用 NVM 的特性。修改了 PostgreSQL 的存储引擎,使之适配 NVM ,并详细描述了如何修改以及修改的挑战。最后通过一个全面的仿真平台对其进行测试评估。结果显示,数据存储在磁盘:修改后的 PG 查询时间比原生 PG 减少 40% ;数据存储在 NVM ,可以减少 14.4% 。平均分别减少 20.5% 和 4.5% 。
引言
一般数据库管理系统都是内存加磁盘的架构,数据集最终会持久化到磁盘。磁盘具有廉价、非易失的特性,适合存储大规模数据。然而,当从磁盘读取数据时,时间比较长。为了减少数据访问的延迟,在CPU 和磁盘直接添加了 DRAM 作为中间存储媒介。 DRAM 的访问速度比磁盘快几个数量级。另外,随着 DRAM 芯片的密度增加以及内存价格的降低,具有大内存的系统变得越来越常见。
基于这些原因,传统的基于内存的关系数据库变得越来越流行。关系型数据库的重要部分,例如索引结构、恢复机制、提交处理过程等都是针对主存作为存储介质而定制的。但是关系型数据库在处理关键数据或者非冗余数据时仍然需要持久化存储介质,例如大量磁盘。
DRAM 是影响数据库服务效率的重要因素。数据库在执行查询时, 59% 的电量耗费在主存上。此外,还有与漏电和电压相关的内置物质限制 DRAM 的进一步扩展。因此, DRAM 作为主要内存介质,不可能跟上当前以及未来数据集的增长。
NVM 是一种新型的硬件存储介质,同时具备磁盘和 DRAM 的一些特性。突出的 NVM 技术产品有: PC-RAM 、 STT-RAM 和 R-RAM 。因为 NVM 具有设备层次上的持久性,所以不需要向 DRAM 一样的刷新周期以维持数据状态。因此 NVM 和 DRAM 相比,每 bit 耗费的能量更少。另外, NVM 比硬盘有更小的延迟,读延迟甚至和 DRAM 相当;字节寻址;比 DRAM 密度更大。
DBMS 设计时需要充分考虑 NVM 的特性以释放其硬件红利。最简单的设计方法是将 NVM 替代磁盘,利用其低延迟以获取性能提升。然而,使 DBMS 适配 NVM 的特性,远远不止其低延迟的特点。
本文,研究了如何在设计DBMS 时部署 NVM 。首先,讨论了如何将 NVM 包含到当前系统的内存结构中;然后通过修改 PostgreSQL 的存储引擎最大化 NVM 的红利。我们旨在绕过缓慢的磁盘接口的同时保证 DBMS 的健壮性。
我们通过使用仿真平台和TPC-H 基准测试用例来评估 PG 的两种修改后的存储引擎。同时,测试了未修改的 PG 在 SSD 和 NVM 上的场景。结果显示,修改后的存储引擎能够减少内核执行时间(文件 IO 发生的位置):平均从 10% 到 2.6% 。修改后的 PG 性能在硬盘上能够提升 20.5% , NVM 上可以提升 4.5% 。另外,证明了修改后的 PG 性能瓶颈:由于直接访问 NVM 以获取数据,所以当查询需要该数据时,改数据不靠近 CPU 。当用户层次的 cache 没有该数据时,造成很长的延迟,就体现不出新硬件带来的好处了。
背景
本小节详细介绍了NVM 技术的特性以及对 DBMS 涉及的影响。然后介绍了管理 NVM 的系统软件。
1 、 NVM 特性
数据访问延迟 :NVM 的读延迟比磁盘小很多。由于 NVM 仍处于开发阶段,来源不同延迟不同。 STT-RAM 的延迟 1-20ns 。尽管如此,他的延迟也已经非常接近 DRAM 了。
PC_RAM 和 R-RAM 的写延迟比 DRAM 高。但是写延迟不是很重要,因为可以通过 buffer 来缓解。
密度 :NVM 的密度比 DRAM 高,可以作为主存的替代品,尤其是在嵌入式系统中。例如,相对于 DRAM , PC-RAM 提供 2 到 4 倍的容量,便于扩展。
耐久性 :即每个内存单元写的最大次数。最具竞争性的是PC-RAM 和 STT-RAM ,提供接近 DRAM 的耐久性。更精确的说, NVM 的耐久性是 10 15 而DRAM 是 10 16 。另外,NVM 比闪存技术的耐久性更大。
能量消耗 :NVM 不需要像 DRAM 一样周期性刷写以维护内存中数据,所以消耗的能量更少。 PC-RAM 比 DRAM 消耗能量显著的少,其他比较接近。
此外,还有字节寻址、持久性。Interl 和 Micron 已经发起了 3D XPoint 技术,同时 Interl 开发了新的指令以支持持久内存的使用。
2 、 NVM 的系统软件
使用NVM 作为主存时,不仅需要更改应用软件还要修改系统软件,才能充分发挥出 NVM 的优势。传统的文件系统通过 block 层访问存储介质。如果仅仅只是将磁盘替换成 NVM ,而不作任何修改,那么 NVM 存储也需要通过 block 层才能读写数据。因此 NVM 字节寻址的特性不能充分发挥出其优势。
因此,文件系统支持持久内存上已经有了一些进展。PMFS 是一个由 Interl 开发并开源的 POSIX 文件系统。它提供 2 个关键特性以方便使用 NVM 。
首先,PMFS 不为 NVM 维护独立的地址空间。换句话说, NVM 和内存统一寻址。这意味着不需要将数据从 NVM 拷贝到 DRAM 以便应用访问。进程可以以字节的粒度直接访问 NVM 中的数据。
其次,传统数据库以两种方式访问blocks :文件 IO ;内存 mapped IO 。 PMFS 以类似传统 FS 的方式实现文件 IO 。然而,内存 mapped IO 的实现方式不同。传统文件系统中内存 mapped IO 先将 pages 拷贝到 DRAM 。 PMFS 则不用这个步骤,它直接将 pages 直接映射到进程的地址空间。图 1 为传统文件系统与 PMFS 对比。
设计的选择
本小节,讨论了系统包含NVM 时存在的内存分层设计方案以及为充分利用 NVM ,对面向磁盘的 DBMS 如何修改。
1 、基于 NVM 的 DBMS 内存分层设计
有各种方法将NVM 放在当前 DBMS 的内存层次结构中。图 2 展示了几种使用 NVM 的三种常见。其中 a 图为传统的方式,当前使用的中间状态包括日志、数据缓存、部分查询状态,存放在 DRAM 中,主要数据存放于磁盘。
基于NVM 的特性,可以将其替换 DRAM 和磁盘。如 b 图所示。然而,这样的改动需要重新设计当前的操作系统和应用软件。另外,作为 DRAM 的替代品, NVM 技术在耐久性方面并不成熟。因此,我们主张平台中仍然包含 DRAM 内存,磁盘全部或部分被替换成 NVM 。如图 c ( NVM-Disk )所示。
这种方案中,仍在当前系统中保留DRAM 层,从而利用 DRAM 快速读写临时数据结构和应用代码。另外,允许应用通过 PMFS 文件系统访问数据库系统的数据,利用 NVM 字节寻址的特性避免当前传统文件系统的 API 开销。这样的部署方式不需要大量的 DRAM ,因为临时数据量比较小。我们认为这种部署场景是为了集成 NVM 的合理使用方式:将 NVM 放置 DRAM 旁以存储临时数据结构或者使用传统磁盘存放冷数据。
2 、传统 DBMS 的改动点
将传统面向磁盘的数据库系统直接部署在NVM 上时,不能充分发挥出 NVM 新硬件带来的红利。当使用 NVM 作为主要存储介质时, DBMS 的重要部件需要更改或移除。
避免块级别的访问 :传统的DBMS 使用磁盘作为主要存储介质。由于磁盘顺序访问速度较快,所以以数据块的形式读取来平衡磁盘访问延迟。
不幸的是,以块的形式访问数据会造成额外的数据移动成本。例如,如果一个事务更新了一个记录的一个字节,仍然需要将整个块刷写到磁盘。换句话说,块级访问提供了较好的数据预读。由于NVM 是字节寻址,可以字节的形式访问数据。然而,这样将数据粒度降低到字节级别,没有了数据预热性。一个较好的方法需要平衡这两方面的优点。
移除DBMS 的内部 buffer cache :DBMS 通常维护一个内部的 buffer cache 。当访问一个记录时,首先计算出他的磁盘地址。如果数据对应的 block 不在 buffer cache ,就需要从磁盘读取到 buffer cache 。
基于NVM 的数据库就不需要这样的方法了。如果 NVM 的地址空间可以被其他进程可见,那么久不需要再做 block 拷贝的动作。直接访问 NVM 中的记录会更高效。然而,这就需要一个支持 NVM 的操作系统,例如 PMFS ,可以直接将 NVM 地址空间暴露给进程。
移除redo 日志 :为了保证数据库的ACID 属性, DBMS 需要两种日志: undo 和 redo 。 Undo log 用来回滚未提交的事务, redo 用来回放已提交但未写到磁盘的数据。基于 NVM 的 DBMS 中,如果不部署内部的 buffer cache ,所有写直接写到 NVM 时,就不需要 redo log 了,但是 undo log 仍旧需要。
案例:POSTGRESQL
Postgresql 是一个开源关系型数据库,支持完成的 ACID ,并能够运行在所有主流的操作系统上,包括 Linux 环境。本小节我们研究了 postgresql 的存储引擎和做一些修改使之适配 NVM 。先介绍了 PG 的读写架构,然后解释做了哪些修改。
1 、 PG 的读写架构
图3a 展示了原始 PG 的读写文件操作的架构。左边一列的图显示了 PG 软件层执行的操作,右边一列展示了对应的数据移动。注意,使用的操作系统是 PMFS 。图 3a 中使用 NVM 替代磁盘以存储数据。
PG 读写数据的性能严重依赖于文件 IO 。由于 PMFS 的文件 IO 的 API 和传统文件系统的一样,所以使用特定的文件系统对于 PG 来说不用做任何修改。
PG server 调用 Buffer Layer 的服务,用于维护内部的 buffer cache 。 Buffer cache 中维护这 PG 即将被访问的页。如果 buffer cache 没有空闲 slot 以供磁盘读取一个页进来,就会执行替换策略,即选择一个数据页从 buffer cache 的管理链表中驱逐供之使用,如果该数据页是脏页,则需先将其刷写到磁盘。
PG 一旦接收到一个从磁盘读取数据页的请求, Buffer Layer 就会在 buffer cache 中找一个空闲 slot 并得到他的指针。图 3a 中 pg Buffer 和 PgBufPtr 分别是空闲的 buffer slot 和对应的指针。 Buffer Layer 将这个指针传输给 File Layer 。最终 PG 的 File Layer 唤醒文件读和写,读和写依赖于文件系统来完成。
对于读操作,PMFS 将数据块从 NMV 拷贝到内核的 buffer ,然后内核将之拷贝到 PgBufPtr 指向的空闲 buffer cache slot 。写操作的话也是两次拷贝,只不过方向相反。
因此,当未命中buffer cache 时,原生 PG 的存储引擎会引发两次拷贝动作。当数据集非常大时,这将是一个很大的开销。由于 PMFS 能够将 NVM 地址直接 map 到内存,可以通过修改存储引擎,避免拷贝的开销。下面介绍如何改动。
2 、 SE1 :使用内存 map 的 IO 方式
利用NVM 特性的第一步:将 PG 的 File Layer 替换掉,命名为 MemMapped Layer 。如图 3b 所示,这一层仍然接收 Buffer Layer 传来的空闲 buffer slot 的指针。但是,通过使用 PMFS 的内存映射输入输出接口,不再产生文件 IO 。将这样的存储方式称之为 SE1 。
读操作 :当访问文件进行读时,首先需要调用open() 将文件打开,然后需要使用 mmap() 将文件映射到内存。由于使用 PMFS , mmap() 会返回 NVM 中文件的映射指针。这就可以是应用直接访问 NVM 上的文件。
因此,不需要将请求的数据页拷贝到内核buffer 中。如图 3b 所示,可以调用 memcpy() 将请求的数据页直接拷贝到 PG 的 buffer 中。当请求完成,不再需要访问该文件时,可以将文件关闭。之后,就可以调用 munmap() 函数取消映射。
写操作 :和读操作类似。首先需要将即将更改的文件打开,然后mmap 映射。使用 memcpy() 直接将脏数据从 PG buffer 中拷贝到 NVM 。
SE1 ,不必将数据拷贝到内核 buffer ,减少了一次数据拷贝。
3 、 SE2 :直接访问映射文件
第二种修改方法是,将SE1 的 MemMapped Layer 替换为图 3c 的 PtrRedirection Layer 。和 MemMapped Layer 不同,他接收到的是指向 PgBufPtr 的指针( P2PgBufPtr )。
读操作 :当访问文件进行读操作时,调用open() 打开文件,然后使用 mmap() 映射到内存。原来的 PgBufPtr 指针指向内部 buffer cache 的空闲 slot 。因为 mmap 可以将 NVM 映射到内存,即进程可以看到这个地址, PtrRedirection Layer 将 PgBufPtr 指向 NVM 上文件的地址。读操作的指针重定向如图 3c 的“ Read ”标签所示。
因此读操作时不再需要数据拷贝。在大数据查询中,这种方法对性能有很大提升。
写操作 :PMFS 可以使应用直接访问 NVM 上的文件。由于 PG 是个多进程系统,直接更改 NVM 上文件非常危险,可能使数据库处于不一致的状态。为了避免这个问题, SE2 在修改数据页并标记为脏页前还需 2 步:如果页在 NVM 中,那么将数据页拷贝到内部 buffer cache ,即 Pg-Buffer ;然后解除 PgBufPtr 重定向指针,重新指向 buffer cache 的空闲 slot 。如图 3c 的“ Write ”流程。通过这种方法, SE2 就能保证每个进程只更改其本地的数据页副本。
相关工作
之前的工作主要分为两类:用NVM 将整个数据库存储介质替换掉;部署 NVM 存储日志。《 Nvram-aware logging in transaction systems 》和《 High performance database logging using storage class memory 》减少磁盘 IO 对事物吞吐量的影响,以及将日志直接写入 NVM 而不是刷到磁盘以减少相应时间。多核多 socket 的硬件上使用 NVM 写分布式日志,当系统负载增加时减少集中式日志记录的竞争:《 Scalable logging through emerging nonvolatile memory 》。 DRAM 和 NVM 两层存储,研究不同的恢复方法。
结论
研究了在设计DBMS 时,部署 NVM 对其影响。谈论了将 NVM 加入 DBMS 内存层次中的几种情形。将 NVM 完全或者替代部分磁盘是一种典型的应用场景。这种方法下,原理系统不用修改,并允许直接访问 NVM 上的数据集。介绍了 PG 存储引擎的两种变种: SE1 和 SE2 。
实验结果表明,对于原生PG ,将数据库部署在 NVM 比磁盘上性能最高提升 40% ,平均提升 16% 。 SE1 和 SE2 相对于磁盘下能减少执行时间近 20.5% 。然而,当前数据库系统的设计最大障碍在于将性能提升最大化。比较我们基准和 SE2 ,能够最大提升读性能 14.4% ,平均 4.5% 。
限制因素在于数据离CPU 比较远,这是直接访问 NVM 上数据的负面影响。这会使 NVM 带来的优势减弱。因此开发适配 NVM 的库非常必要。