获取存储引擎准备好快速存储设备
在过去的二十年里,存储硬件的性能提高了两个数量级。首先是固态硬盘(SSD)的引入,然后是SATA向PCIe的过渡,最后是非易失性存储器技术和制造工艺的创新[1,7]。最近,在四月2019年,Intel发布了第一个商用存储级内存(SCM)。它的Optane DC永久记忆与3D XPOINT技术构建,位于存储器总线上,并进一步降低了I / O延迟[2]。
虽然设备访问用来支配I / O等待时间,进行导航的存储系统的软件栈的成本正变得作为设备的访问时间收缩更加突出。1888bet亚洲体育188金宝慱官网下载这是导致学术研究乱舞和改变商业上使用的操作系统(OS)和文件系统。尽管有这些努力,主流系统软件无法跟上快速发展的硬件。1888bet亚洲体育188金宝慱官网下载学习 [4,五,6已经证明,文件系统和其他操作系统开销仍然在非常快的存储设备(如SCMs)的I/O成本中占主导地位。
为了应对这些挑战,学者提出了一个新的用户级文件系统,SplitFS [6],即显着地降低这些费用。不幸的是,采用用户级别的文件系统不适合许多商业产品的可行选择。除了约正确性,稳定性和维护问题,采用SplitFS的将限制便携性,因为它只能运行在Linux和仅在ext4的DAX文件系统之上。
幸运的是,有IS东西,可以在关心I / O性能的软件存储引擎来完成。1888bet亚洲体育188金宝慱官网下载在MongoD188金宝搏手机客户端安卓下载B的存储引擎,WiredTiger,我们能够基本去除刹车文件系统应用到我们的表现在不牺牲它提供了便利条件或失去便携性。我们的变化依赖于使用内存映射文件I / O和昂贵分批文件系统操作。这些变化导致了高达63%的性能提升为主流固态硬盘中的19 65点的基准。
简化的I / O WiredTiger
我们对WiredTiger变化由加州大学圣地亚哥分校[研究的启发4],其中作者证明,通过使用内存映射文件I / O,并通过预分配文件中的某些额外的空间时,它需要的增长,因为如果文件系统是完全不存在的,他们可以实现几乎相同的性能。
内存映射文件
内存映射文件的工作方式如下。所述应用程序发出MMAP系统调用,由此请求操作系统“地图”的虚拟地址空间的其选择(图1中步骤1)的文件中的块的尺寸相同的块。当在首次(例如,虚拟页0xABCD图1)的虚拟地址空间的那一部分访问存储器,所述发生以下事件:
- 由于这是一个以前没有访问过的虚拟地址,所以硬件将生成一个陷阱并将控制权转移给操作系统。
- 操作系统将确定这是一个有效的虚拟地址,询问文件系统文件读入到它的高速缓冲存储器的相应页面大小的部分,
- 创建在缓冲区缓存(例如,物理页0xFEDC图1),一个页表条目映射用户虚拟页的物理页文件所在(步骤2在图1中)的那部分。
- 最后,虚拟到物理地址的转换会被插入到转换后备缓冲器(TLB - 硬件缓存这些翻译),以及应用程序将数据访问进行。

内存映射文件的工作原理如下:(1)它们为映射文件建立一个虚拟内存区域,(2)它们将虚拟到物理地址转换放到页表中,(3)它们将转换缓存到translation Lookaside Buffer (TLB)中
后续访问同一个虚拟页面可能需要操作系统参与,也可能不需要操作系统参与,具体取决于以下几点:
- 如果包含文件数据的物理页面仍然在缓冲区高速缓存和页表项是在TLB,操作系统的参与是没有必要的,并且数据将使用常规的加载或存储指令访问。
- 如果包含文件数据的页面仍然在缓冲区高速缓存,而TLB项被拆迁户,硬件将过渡到内核模式,走在页表中查找条目(假设x86架构),它安装到TLB,然后让软件访问使用常188金宝慱官网下载1888bet亚洲体育规的加载或存储指令的数据。
- 如果包含文件数据的页面不在缓冲区缓存中,硬件将陷进操作系统,操作系统将要求文件系统获取页面,设置页表条目,并按照场景2进行操作。
相反,系统调用跨越用户/内核边界每一次我们需要访问的文件。即使存储器映射的I / O还越过如上所述的第二和第三方案的用户/内核边界,它需要通过系统栈路径是比由系统调用采取更有效。调度和系统调用返回增加CPU开销内存映射I / O没有[8]。此外,如果数据是从所述存储器映射的文件区到另一个应用程序缓冲区复制,这将典型地使用memcpy的高度优化的基于AVX的实现。当数据被从内核空间分成经由系统呼叫的用户空间复制,内核使用一个低效率的实施方式中,因为内核不使用AVX寄存器[8]。
预分配文件空间
存储器映射文件允许我们访问固定大小的文件时,显着地降低OS的参与和文件系统。如果文件大小,但是,我们确实需要涉及到文件系统。该文件系统将更新文件元数据,以表明其新的大小,并确保这些更新生存崩溃。
确保崩溃一致性是特别昂贵的,因为每个日志记录必须保存到存储,以确保它不会在发生碰撞的情况下丢失。如果我们零碎长出了文件,我们承担的是开销经常。这就是SplitFS为什么作者[6和UCSD研究的作者[4当应用程序扩展文件时,它们都会预先分配一个大的文件块。从本质上说,就是这个策略批处理文件系统操作以减少它们的开销。
我们的实现
球队在两个阶段应用这些想法WiredTiger。首先,我们实现,其中映射文件区域的大小不会改变设计。然后,确保后,这个简单的设计作品和产量的性能提升,我们增加了他们扩大或缩小重新映射文件的功能。这个功能需要高效的线程间的同步,是整个设计的最棘手的部分 - 我们在本节后面高亮显示。
我们的变化已经在WiredTiger的开发分支测试在2020年1月担任的写作的时间,这些变化只对POSIX系统;一个Windows端口对未来的计划。
假设映射的文件区域大小固定。
实现这个部分需要一些代码更改。WiredTiger提供包装的所有文件相关的操作,所以我们只需要修改这些包装。打开文件时,我们发出mmap系统调用来把它映射到虚拟地址空间。后续调用读取或写入该文件将文件的所需部分从映射区域复制到提供的缓冲区包装。
WiredTiger允许三种方式增长或收缩文件的大小。该文件可以通过fallocate系统调用(或同等学历),它可以隐式成长,如果发动机写入超出其边界的文件,或文件可以通过截断系统调用缩水明确增长。在我们的初步设计,我们不允许明确增长或文件,但不影响发动机的正确性萎缩。如果发动机写入文件以外的映射区域,我们的包装函数只是默认使用系统调用。如果发动机然后读取尚未被映射文件的一部分,我们还诉诸使用系统调用。
虽然这个实现是体面作为早期的原型,它的局限性太大了生产系统。
调整映射文件区域的大小。
这一功能的最棘手的部分是同步的。想象一下,涉及到两个线程,其中一个读取文件,另一个截断它下面的场景。在此之前的阅读,第一个线程会做映射缓冲区的检查,以确保抵消从中读取是映射的缓冲区的边界之内。假定它是,它将着手将数据从映射缓冲区拷贝。但是,如果只是复制和截断文件,以便新的大小小于偏移量从第一线程读取之前第二个线程介入,第一个线程试图复制数据会导致崩溃。这是因为映射的缓冲器比截断后的文件大,并试图将数据从延伸超过文件的结尾将产生段故障缓冲区的一部分复制。
防止这个问题的一个明显的方法是每次我们需要访问的文件或改变其大小时获得锁。不幸的是,这将序列化I / O,并可能严重影响性能。相反,我们使用由读 - 复制 - 更新(RCU)的启发无锁同步协议[9]。我们将把可能改变文件的大小为所有线程作家。一个作家,因此,这是写入超出文件的末尾,通过fallocate系统调用,或截短它扩展了它的任何线索。一个读者读取文件的任何线程。
我们的解决方案如下:写入器首先执行更改文件大小的操作,然后将文件重新映射到虚拟地址空间中。在此期间,我们希望没有其他人访问映射的缓冲区,无论是读取器还是写入器。然而,没有必要在此时阻止所有I/O的发生;当写入器操作映射的缓冲区时,我们可以简单地将I/O路由到系统调用,因为系统调用在内核中与其他文件操作正确同步。
为了实现无锁定这些目标,我们依赖于两个变量:
- mmap_resizing:当编写器想要向其他人表明它将排他性地操作映射的缓冲区时,它会自动设置这个标志。
- mmap_use_count:在使用映射缓冲区之前,读取器会对计数器进行递增,完成后会对计数器进行递减。这个计数器告诉我们当前是否有人在使用缓冲区。写入器将等待该计数器变为零后再继续。
- 调整的文件和映射缓冲区前,作家执行函数prepare_remap_resize_file;其伪代码如下所示。从本质上讲,笔者有效地等待,直到没有人是在调整的缓冲,然后将调整大小的标志要求独家代理权操作。然后,它等待,直到所有的读者正在使用的缓冲区来完成。
prepare_remap_resize_file:等待:/ *等到没有其他人是在调整的文件* /而(mmap_resizing!=0)spin_backoff( );/ *原子方式设置调整的标志,如果失败重试。* /结果=中科院(mmap_resizing,1,...);如果(结果)去等待;/ *现在,我们设置的调整标志,等待所有的读者使用缓冲完成* /而(mmap_use_count>0)spin_backoff( );
执行后prepare_remap_resize_file
,作者执行所述文件调整大小的操作,取消映射缓冲器中,与新的大小重新映射它并复位调整大小标记。
由读取器执行的同步在该函数的伪代码中示出read_mmap
:
read_mmap:/*原子递增引用计数器,*所以当我们使用它没有一个取消映射缓冲区。* /atomic_add(mmap_use_count,1);/ *如果缓冲器被调整大小,使用系统调用的,而不是映射的缓冲器。* /如果(mmap_resizing)atomic_decr(mmap_use_count,1);read_syscall( );其他的memcpy(dst_buffer,mapped_buffer,...);atomic_decr(mmap_use_count,1);
边注,线程编写文件必须执行读者同步,在read_mmap,看看他们是否可以使用I / O的内存映射缓冲区,和作者同步在过去他们在写文件的末尾(因此扩展它的大小)。请参阅WiredTiger开发分支查看完整的源代码。
配料文件系统操作
正如我们前面提到的,加州大学圣地亚哥分校的研究的重要发现,激发了我们的设计[4],是由大块预分配文件空间的需要批量昂贵的文件系统操作。我们与WiredTiger实验表明,它已经使用这种策略在一定程度上。我们跑了比较两种配置实验:(1)在默认配置WiredTiger使用fallocate
系统调用成长文件。(2)在限制不允许使用WiredTiger配置fallocate
因此,通过编写超过其末端的文件,求助于隐式地增长文件。我们测量了这两种情况下的文件系统调用数量,发现在默认配置中调用的数量比在受限配置中至少要小一个数量级。这告诉我们WiredTiger已经对文件系统操作进行批处理。未来是否计划对批处理进行优化以进一步提高性能。
性能
为了衡量我们的变化带来的影响,我们比较的性能mmap
WiredTiger基准测试套件WTPERF上的分支和开发分支。WTPERF是一个可配置的基准测试工具,它可以模拟各种数据布局、模式和访问模式,同时支持各种数据库配置。在65个工作负载中,mmap分支提高了19个工作负载的性能。其余工作负载的性能或保持不变,或显示不显著的变化(在平均值的两个标准差范围内)。两种工作负载(更新日志结构的合并树)的性能差异增加了几个百分点,但除此之外,我们没有观察到使用mmap的任何缺点。
下图显示的性能改善,以百分比表示,相对于MMAP分公司开发的19个基准,其中MMAP了一定的作用。该实验用的系统上运行Intel Xeon处理器E5-2620 v4(八个核心),64GB内存和英特尔PRO 6000P系列512GB固态硬盘驱动器。我们使用的所有基准默认设置和运行每个至少三次,以确保结果的统计显著。

所有哪来MMAP了一定的作用基准的2显示显著改善
总体来说,有很大性能改进,使这些工作负荷,但有几个有趣的例外。500米-B树-50r50u和用于更新-B树的一些操作(例如,更新或插入)是慢一点与MMAP,但其他(通常读取)基本上更快。看来,某些操作从以邻为壑MMAP受益;我们仍在调查为什么发生这种情况。
一,说明使用mmap改进性能的变量增加的I / O速率。例如,对于500米-B树-50r50u工作量(在此工作负载模拟典型的MongoDB负载)所读出的I / O速率高约30%,大于MMAP与系统调用。188金宝搏手机客户端安卓下载这一统计数字并不能说明一切:毕竟,读取吞吐量为这个工作量是63%,使用mmap优于与系统调用。最有可能的,差异的其余部分是由于存储器映射的I / O更有效的代码路径(而不是通过系统调用去),如在先前的工作观察到8]。实际上,在使用mmap时,我们通常会观察到更高的CPU利用率。
结论
吞吐量和存储设备的延迟以较高的速率比由于存储技术的重大创新和系统设备的放置CPU速度提高。更快的存储装置揭示软件堆栈效率低下。1888bet亚洲体育188金宝慱官网下载在我们的工作中,我们专注于开销相关的系统调用和文件系统访问并展示了如何可以通过使用内存映射I / O进行导航。我们在WiredTiger存储引擎的变化产生了高达读取吞吐量63%的改善。对于我们实现的更多信息,我们建议您看看文件os_fs.c和os_fallocate.c在os_posix目录的WiredTiger开发分支。
参考文献
[1]英特尔ssd列表。https://en.wikipedia.org/wiki/List_of_Intel_SSDs
Optane DC持久存储器。https://www.intel.ca/content/www/ca/en/architecture-and-technology/optane-dc-persistent-memory.html
[3]Linux®的存储系统分析e.MMC与命令队列,https://www.micron.com/-/media/client/global/documents/products/white-paper/linux_storage_system_analysis_emmc_command_queuing.pdf?la=en
[4]徐坚,朱诺金,Amirsaman Memaripour,和史蒂芬·斯旺森。2019年发现和修复性能病状永久记忆软件栈。1888bet亚洲体育188金宝慱官网下载在计划 - 铭语言和操作系统(ASPLOS '19)2019架构支持。http://cseweb.ucsd.edu/~juk146/papers/ASPLOS2019-APP.pdf
[5] Jian Xu和Steven Swanson, NOVA:一种用于混合易失性/非易失性主存储器的日志结构文件系统,第14届USENIX文件和存储技术会议(FAST ' 16)。https://www.usenix.org/system/files/conference/fast16/fast16-papers-xu.pdf
[6]罗汉Kadekodi,硒权利,Sanidhya卡什亚普,Taesoo金,Aasheesh Kolli,和维杰奇丹巴拉姆。2019年SplitFS:减少持久性存储器中的文188金宝慱官网下载1888bet亚洲体育件系统软件开销。在第27届ACM研讨会作业系统原理(SOSP '19)的诉讼。https://www.cs.utexas.edu/~vijay/papers/sosp19-splitfs.pdf
[7] SDD VS HDD。https://www.enterprisestorageforum.com/storage-hardware/ssd-vs-hdd.html
[8]为什么MMAP比系统调用快。https://medium.com/@sasha_f/why-mmap-is-faster-than-system-calls-24718e75ab37
[9]保罗·麦金尼。RCU到底是什么?https://lwn.net/Articles/262464/