傲腾️™PMem +SPDK为百度用户态存储引擎注入新思路

存储之痛

最近几年存储介质得到了快速发展,单位存储介质的性能越来越高,原来 HDD 机械硬盘读写速度不足 100 IOPS,如今 NVMe SSD 可以达上百万 IOPS,时延从毫秒压缩到微秒,系统的性能瓶颈也由存储硬件本身逐渐转移到网络及处理器上,传统文件系统、调度器等方法无法充分发挥新存储介质的性能,成为存储系统的新瓶颈。尤其对于大型互联网后端系统,这些瓶颈不仅会对业务系统带来低效率,而且会影响到系统可靠性。

比如,元数据对性能瓶颈更加敏感。元数据在存储系统中大多是为索引而存在的。当数据写入后,有效期内数据几乎很少移动,但是元数据却需要频繁整理和移动。每次数据的变动,都会改变索引结构,因此需要频繁、及时的更新索引,以保证数据的高效和正确。在现有的索引结构中,索引的重建和重组,会面对有效索引记录、失效索引标记、索引空间回收等问题;在索引重建时还会出现时间开销,这些消耗,在复杂的存储系统里会被逐渐放大,影响整个系统的性能。

与此同时,传统内核态存储系统中的几个弊端,也使系统的维护难度加大,运维成本增加。首先在业务量较大的场景下,内核态存储容易造成 CPU 资源消耗过高。这是因为在内核中,CPU资源是抢占式调度,每个进程都需要等待 CPU 空闲时才能调度处理,因此业务量增大、进程增多 CPU 资源就会被过高占用。

其次在存储系统工作中,会出现因为单节点故障而造成整个系统停摆的风险;在内核态系统中,单机如果出现内核错误或漏洞,需要停掉主机,寻找原因修复补丁或升级内核,主机下线会对运行在上层的业务造成严重影响。第三在内核的日常维护中,如需升级内核组件,需要下线主机,停止主机上的所有业务,对内核或者驱动进行升级;除此之外内核或驱动的升级,有可能会给系统带来新的系统性风险。这些问题给系统的维护带来极大的不便,运维成本也显著升高。

百度妙招

为了实现存储系统的可靠性、扩展性、高性能,低运维成本,百度单机引擎开发团队推出了基于英特尔® 傲腾™ 持久内存和存储性能开发套件的用户态存储引擎,用以满足各业务产品对数据存储的挑战。新单机存储引擎支持 KV、file、block 等多种应用接口,可应用于块存储、文件存储、对象存储等多种应用场景,满足不同业务的存储需求。该单机引擎还研发了创新的存储计算分离结构,领先的分布式架构,灵活的数据分层、用户态软件栈、本地/远程多种存储设备的兼容等等。

PMem缓存层

研发团队选择使用英特尔® 傲腾™ 持久内存作为引擎缓存层的存储介质。英特尔® 傲腾™ 持久内存(以下简称 “持久内存” 或者 “PMem”)是一种颠覆传统的内存产品,基于 3DXpoint 介质,具有高速、低延迟、高性价比、大容量、持久数据保护、高级加密等优势。它改变了原有的存储层次结构,可以提供类似于 DDR 内存(简称“DRAM”)的性能,并且可以像 SSD 那样持久地存储数据,同时持久内存比 DRAM 容量更大,价格也更为便宜。

此图像的alt属性为空;文件名为2021070503410912.png

从新引擎的工作线程中我们看到,在系统读写的过程中会频繁的修改和整理索引,由此引发的索引重建、重组等时间开销会大量占用系统资源。使用应用直接访问模式下的持久内存作为缓存层,将索引数据存储在持久内存上,通过持久内存开发工具包(PMDK)进行内存调度,可以加速元数据的读写,最大程度减少资源损耗。

在传统的存储系统中,Buffer 会被写入文件系统的 Page Cache中,Page Cache 的空间大小直接影响系统写的性能。如果存储系统碰到突然爆发的写入压力,Page Cache 受空间所限,堆积在内的数据还未来的及写入磁盘,新增加的数据无法写入 Buffer,最终导致数据延迟性能下降。而在新单机引擎中,Buffer 被写入大容量的持久内存中,数据的读写能力与 DRAM 相近。

为了验证实际效果,研发团队对写入 Buffer 数据进行了测试。随机写入一个 4K 的数据,通过工具统计的延迟是 4.5μs,如下表所示,图中 NTstore 为写入持久内存的时间消耗,大约只有1μs,其余时间消耗都为软件其它开销;如果将 PMem 换成内存,延迟大约 1μs 的1/10,100ns,4K 数据写入的时间在 3μs 左右,与PMem 延迟相差不大。

此图像的alt属性为空;文件名为202107050341317.png

性能相近,总拥有成本却降低很多。相同的成本投入,PMem 的空间是 DRAM 的三倍,因此可以缓存更多数据,提高存储系统性能;此外通过 PMem 缓存数据后,会以更加合理的方式存盘,可以有效提高后端存储设备的 IO 效率。

PMDK加持好马配好鞍

持久内存设备遵循 SNIA 编程模型,同时英特尔为其提供了一套持久内存开发套件 PMDK。PMDK 可以帮助应用来直接访问持久内存设备而不需要经过文件系统的页高速缓存系统、系统调用和驱动,减少了许多流程,避免了数据输入/输出(I/O)产生的开销,大大降低数据延迟。

新单机引擎,使用持久内存存储元数据、缓存和索引,通过结合SPDK 提供的多种后端存储支持,提供不同的解决方案。SPDK2 提供了一组工具、库和方案,用于编写高性能和可扩展的用户态存储应用程序。

它通过使用多种关键技术来实现高性能和高扩展,诸如将一些驱动程序移至用户空间,避免了系统调用,并允许从应用程序进行零拷贝访问,通过无锁化、消息机制和异步编程来实现高性能应用框架,同时提供统一的用户态通用块设备来高效管理不同的存储后端设备。

使用 SPDK 之后,用户态的驱动通过轮询硬件而不是依赖中断来完成,这可以降低总延迟和减少延迟差异,并且和内核驱动相比,在每个 CPU 内核的 IOPS 上具有更明显的性能优势;此外,SPDK 具备 I/O 路径的无锁高性能模式,避免了所有在 I/O 关键路径中的锁,而是依靠消息传递在多个线程中共享资源,从而提高了并行性。

SPDK 可以高效整合英特尔的 CPU 处理、存储和网络技术,将高性能存储介质的性能潜力充分发挥出来,同时高性能框架提供统一的设备管理来支持多种多样的存储后端。

性能测试

测试中分别对使用持久内存的新单机引擎,纯 NVMe 和纯 HDD 的传统引擎进行随机 16K 数据的读写测试(QD为线程数量),从测试结果可以看出,新单机引擎的读写性能提升了10-20倍,在性能提高的同时,控制了总体拥有成本。