现如今,互联网产生和累积的数据越来越多.根据思科系统公司的报告,2016年的全球互联网流量已经突破了1 ZB,平均每个月新增96 EB流量.其中忙碌时段的互联网流量相比以往增长了51%,普通时段的互联网流量相比以往增长了32%.此外,报告预测2021年的全球互联网流量将达到3.3 ZB,此间的复合年增长率将达到24%[1].互联网数据规模和高峰流量的爆发式增长,给数据管理系统带来了非常大的考验.
随着数据时代的到来,企业对大数据处理的性能需求日渐提高.传统关系型数据库为了保证数据的原子性、一致性、隔离性、持久性,导致数据操作开销大、效率低,且随着数据规模的快速增长,其在可缩放性、可扩展性方面几乎已经达到极限.键值(key-value, KV)存储系统以key-value对的形式对数据进行存储和索引,摒弃了对新型业务需求而言开销过高的冗余数据管理机制,通过“键”即可快速查询到对应的“值”,具备快速小消息交换、高并发、高吞吐、易伸缩易扩展等的优势,适用于不涉及复杂关系的数据应用场景.
key-value存储系统往往承担着缓冲或存储互联网热点数据、应对高峰流量、保障用户体验的重任,其始终对性能有着很高的要求.随着底层新型网络与存储硬件(如100 Gbps以太网、PCIe固态存储)性能的迅速提高,操作系统内核逐渐成为限制key-value系统吞吐能力的瓶颈.例如内存数据存储系统Redis在完成读操作(GET)和写操作(SET)时,内核网络栈的开销可分别占整体延迟的62%和84%[2].存储方面,虽然对传统机械磁盘而言,数据访问过程中的软件存储栈开销相比硬件处理开销可以忽略不计,但对新型高性能存储(如PCM,3D XPoint,RRAM等),操作系统开销在数据访问中的占比可高达90%[3].
用户级I/O技术通过旁路操作系统内核并针对应用需求定制软件栈以达到避免传统系统软件不足或开销的目的.由英特尔公司开源的用户级网络框架DPDK(data plane development kit)[4]和用户级存储框架SPDK(storage performance development kit)[5]是用户级技术的代表,其提供了用户态的设备驱动,并采用了轮询、大页、核绑定、免锁队列等不同于传统内核设计的机制,降低了系统软件层面的开销,取得了较为显著的性能提升.例如相比Linux内核,SPDK的总体延迟可改善10倍,单个CPU核可提供超过350万次IOPS(input/output operations per second)吞吐量,并使8块NVMe(non-volatile memory express)固态硬盘SSD(solid state drive)达到饱和[3].不过,此类用户级技术侧重暴露硬件底层机制与接口,其接口不够友好,往往要求应用重构代码并实施复杂的优化以收获性能.再者,现有用户级软件栈大都只提供或网络或存储单方面的解决,而上层真实应用往往对需要二者协同优化以取得理想的性能.此外,从底层硬件角度,以PCIe SSD为代表的高性能存储设备的访问延迟和带宽已经与主流高速以太网络达到同一个数量级,网络和存储的性能逐渐匹配,为网络栈与存储栈的统一融合提供了契机.
本文聚焦key-value存储系统的数据通路,面向高速以太网与NVMe SSD,于用户态整合网络栈与存储栈,协同设计以优化系统的吞吐性能与延迟稳定性.控制平面采用核专门化(core specialization)的方法,由单一处理器核“专门”统一管理网络与存储,最小化系统软件开销.数据平面通过统一内存池并于设备之间直接发起直接内存访问(direct memory access, DMA)通信,避免冗余的数据拷贝.测试结果表明,与Twitter公司开源的Fatcache[6]相比,每秒查询(queries per second, QPS)吞吐量提高了近1倍,p95延迟降低了约50%.
本文的主要贡献有3个方面:
1) 面向key-value存储系统提出了一种全用户态的网络与存储协同优化的方法,控制路径由专核统一管理网卡与固态盘设备,减少软件层面的干涉,数据通路采取统一的DMA中转内存池,避免额外数据拷贝.
2) 针对大消息数据访问请求,提出了联合网络与存储的优化方法,将数据分片并交叠执行网卡与固态盘的DMA操作,进一步掩藏延迟.
3) 实现了全用户态key-value存储系统UKV,其支持内存-固态盘2层存储以及广泛使用的Memcache[7]接口.测试结果表明其网络I/O性能优于Twitter Fatcache.
本文的基于用户级融合I/O的key-value存储系统UKV面向高速以太网与NVMe SSD存储,采用直通式的I/O架构,支持内存-固态盘2级存储层级以及Memcache文本接口.首先,UKV基于DPDK与SPDK提供的用户级设备驱动,分别搭建轻量级的网络通路和存储通路软件栈,降低软件开销并完全旁路操作系统内核,消除了内核的性能限制.然后,在全用户态硬件资源直接访问的基础上,整合网络栈与存储栈,由单一处理器核心紧密统一二者的控制平面和数据平面,进一步降低了“跨栈”进出的软件开销.最后针对由网络到存储的完整数据通路,直接调度设备DMA引擎,通过数据分片流水进一步掩藏开销、改善性能.
主流key-value存储系统为了提供足够的吞吐能力与延迟表现,其索引和数据都存储于内存.面对爆发式增长的数据规模与热点时段的高峰流量,内存容量渐成瓶颈.由于单机可安装的内存容量有限,且动态随机访问内存(dynamic random access memory, DRAM)功耗高、单位容量价格高,这使得此类key-value系统的内存空间遭遇了可扩展性的挑战.而与内存相比,SSD在容量、价格、功耗等方面有着明显优势,并且考虑到下一代新型非易失存储(non-volatile memory, NVM)与DRAM之间的性能差距将进一步缩小,其完全可以作为内存的扩展,是搭建大规模、低成本、高性能、可扩展存储系统的理想选择.
UKV借鉴了Fatcache的2级存储方法,并进行了改造与扩展.Fatcache将块设备作为内存数据区域的扩展,在接收到数据存储请求后,数据优先写入内存;当内存数据区存满时,将内存数据写入外存,以腾出内存数据区用于接收新的数据写入.Fatcache虽然宣称支持SSD,但其对SSD的支持较为简单,主要的优化手段限于批量聚合对SSD的写入、将随机写转换为顺序写,从而降低写放大、垃圾回收等的影响.由于仍然采用内核接口,无法实现对设备的直接控制以及细粒度的I/O调度.此外,Fatcache使用了slab机制以减少空间浪费,且索引计算开销小、利于快速定位.但是,Fatcache的数据置换采用了较为简单的先进先出(first in first out, FIFO)策略,虽然利于数据的顺序读写,但数据命中率、带宽效率方面不够理想.本文的置换策略改用最近最少使用(least recently used, LRU),并结合slab机制,同时保证外存“冷数据”顺序写入性能与内存“热数据”随机访问命中率,以获得理想的响应延迟表现.
现代SSD设备不仅支持传统的512 B块单位大小,亦支持4 096 B的块大小以降低元数据管理开销,而key-value存储系统中通常存在大量的小消息负载,对此类消息,一个块可以包含多个key-value对.如若同一块的不同key-value对被访问,将导致对该块的重复访问.对此,UKV于用户态对网络栈与I/O栈进行了整合,以避免冗余的设备访问,提高系统的响应性能.
用户级I/O,旨在旁路操作系统内核,面向应用定制、裁剪系统软件栈,避免通用内核限制并最小化软件开销.
1.2.1 用户级网络通信
UKV使用用户级网络框架DPDK和用户级TCP/IP协议栈F-Stack[8]实现用户级网络通信,提高系统的网络数据处理性能和吞吐量.
DPDK只是一个用户级网络的软件库和驱动程序,并不包含网络协议栈.UKV使用了腾讯公司于2017年5月开源的F-Stack.F-Stack是基于DPDK的高性能开源网络框架,其移植了FreeBSD 11.01的TCP/IP协议栈,在提供了完整的网络协议栈功能的同时裁剪了大量的冗余功能,极大地提升了网络吞吐.F-Stack作为粘合剂,紧密集成了DPDK,FreeBSD协议栈和可移植操作系统接口(portable operating system interface, POSIX),易于部署并提供用户级网络访问.
1.2.2 用户级存储
UKV使用用户级存储框架SPDK实现对SSD的直接管理,并结合key-value存储系统需求以及F-stack实现了轻量级的I/O层,降低了存储设备访问过程的软件开销.
本文的融合I/O软件栈遵循经典高性能技术(如远程内存直接访问)控制平面与数据平面分离的原则,又于控制路径与数据路径分别统一管理网络与存储的数据流动,以保证高效的数据通路.
1.3.1 统一控制平面
本文通过核专用化的方式,将同一个线程绑定在固定CPU核心上,并采用“执行至结束”(run-to-completion)模型,于用户态中通过单一的上下文直接访问网卡设备和NVMe设备的底层硬件队列,实现网络与存储控制平面的统一.
在传统内核机制中,网卡设备和存储设备每次完成收发读写请求后,均通过中断机制来通知CPU.整个中断的过程包括保存信息、中断处理、恢复信息等,至少需要300个CPU时钟周期.中断处理、系统调用以及多线程抢占都伴随着上下文切换.上下文切换的开销又包括:翻转特权级、保存和加载寄存器数据、执行系统调度器代码、重新加载TLB(translation lookaside buffer)实例、刷新CPU流水线等.另外,上下文切换以及进程/线程间的抢占式调度会造成CPU的缓存失效.多核环境下,若设备中断接收线程与应用线程位于不同的核心、不同的处理器,将通过处理器间中断进行处理的中转,跨核跨域的数据传输进一步增加了处理开销.此外,操作系统内核不仅引入了厚厚的存储栈处理开销,还可能导致数据在用户态与内核态之间的额外拷贝,影响系统的吞吐.
如图1与图2所示,在传统操作系统机制下,key-value存储系统处理数据存取操作的过程中将涉及多次进出内核态的系统调用、网卡设备和存储设备的多次中断等.而在UKV的统一控制平面下,通过采用轮询机制彻底避免了中断处理的开销,同时由于设备直接驱动,进一步避免了上下文切换.单一上下文中的定制化轻量级软件栈也消除了数据拷贝和冗余软件栈处理开销.
Fig.1 Comparsion of the control path designs of I/O operations of traditional mechanism and unified control plane
图1 传统机制和统一控制平面下I/O操作的控制通路
Fig.2 Comparsion of the scheduling state of the data path of traditional mechanism and unified control plane
图2 传统机制和统一控制平面下数据通路的调度状态
UKV使用同一个线程,绑定在固定CPU处理器核心上,采用run-to-completion模型,同时管理网卡设备和NVMe设备.静态线程绑核的方式避免了线程在核之间的迁移开销,提高了缓存与内存访问的效率.如图3所示,run-to-completion模型指由单一线程负责于单一用户态上下文中处理key-value请求,具体环节包括:
① 网卡接收数据包.网卡在接收到网络数据包后通过DMA直接拷贝到UKV的数据区域,该过程完全于用户空间执行,无额外数据拷贝与管理模式切换;
② key-value系统处理.UKV解析接收到网络数据包和I/O请求,并完成相关的key-value数据管理操作;
③ 提交SSD读写请求.UKV向SSD发起读写请求,该过程同样完全于用户空间执行,额外开销极低;
④ 完成SSD读写操作.UKV于用户空间通过SSD驱动轮询设备完成队列,等待读写操作完成;
⑤ key-value系统处理.UKV生成回复,打包数据或响应并完成相关的key-value数据管理操作;
⑥ 网卡发送数据包.UKV于用户空间将生成的回复通过网卡直接传输.
上述过程不涉及特权模式切换、中断处理以及线程调度,具有很好的数据缓存局部性,最大限度地避免了数据的额外搬移.如若采用传统的多线程资源共享、轮转响应的机制,在访问共享数据时会面临严重的锁竞争,线程抢占、调度会导致缓存之间频繁的数据更新与通信,拉低了效率.
Fig.3 The run-to-completion model
图3 run-to-completion模型
此外,根据文献[9]的测试结果,就目前主流CPU处理器、高速以太网卡、NVMe SSD的性能而言,单一处理器核心可充分发挥出网卡和SSD的性能,故本文暂未考虑多核控制平面的设计.
1.3.2 统一数据平面
简单地说,统一数据平面是指完全于用户空间直接驱动设备驱动,网卡与SSD的设备队列统一调度并紧密耦合,通过设备DMA引擎直接于统一的数据中转内存池中收发数据.
如图4所示,在传统机制下,key-value存储系统在执行接收操作即SET操作时,数据首先由操作系统内核网络缓冲区拷贝到用户态key-value系统的地址空间,再由key-value系统用户空间拷贝到操作系统内核存储缓冲区,经过内核存储栈层层处理后最终写入存储设备.发送操作即GET操作,数据首先由存储设备读取至内核缓冲区,再拷贝至用户态key-value地址空间,再次拷贝入内核网络栈发送.冗长的数据拷贝路径限制了系统吞吐.虽然传统操作系统内核提供了一些机制或功能可用于减少部分拷贝环节,但大都存在一些弊端.以Linux为例,mmap的方式仍然需要额外的CPU数据拷贝,且引入了开销较大的页表映射操作;sendfile机制仅支持内核空间数据的直接网络传输,存在污染内核页缓冲的隐患,且考虑网络传输的异步性,通常仅支持发送端的传输.
Fig.4 Comparison of the data path of I/O operations of traditional mechanism and unified data plane
图4 传统机制和统一数据平面下I/O操作的数据通路
而在统一数据平面的设计下,UKV系统完全于用户空间直接传输数据,接收数据时网卡直接写入、读取数据时直接由SSD传输至应用缓冲,整个数据路径仅涉及单次系统主存中转.且地址空间单一、上下文单一,无需额外的页表处理,不存在污染公共存储资源的副作用.
由硬件设备读取/发送的数据只存储在用户空间,数据无需再于内核空间与用户空间之间频繁来回拷贝,数据传输过程中也不再涉及操作系统内核的干涉.结合图4,更为详细地,网卡直接由UKV系统于用户空间驱动,网卡在接收到网络数据包后,通过DMA直接传输至UKV用户级的数据中转内存池中.UKV通过用户态TCP/IP协议栈获知消息内容,并按照Memcache协议进行解析,得到具体的key-value数据与相应的I/O请求.如若是SET请求,则将同时解析出的key-value对数据写入slab存储.如若是GET请求,则根据key索引确认value的存储位置.如若发生数据置换、读取外存等I/O操作,则通过纯用户态的NVMe驱动向SSD设备直接提交读写请求.若I/O操作为写,则通过用户级驱动提交命令,由设备DMA从中转内存池读取数据并写入存储设备;若I/O操作为读,则由设备DMA直接将数据写入中转内存池.
通过用户态NVMe驱动提交读写操作后,UKV系统轮询设备的完成队列.操作完成后,将value数据落盘状态或读取到的value数据以Memcache协议格式封装并存放于内存中转池.之后于用户态由TCP/IP协议栈封包后直接交由网卡传输.
UKV系统的数据传输路径,包括网卡接收数据包、key-value协议解析、提交SSD读写请求、完成SSD读写操作、key-value格式化、TCP协议栈封包、网卡发送数据包,整体延迟即各个环节延迟的总和.对SET操作而言,得益于slab机制,SET操作于内存中处理后即返回响应,性能路径不涉及SSD访问,故而瓶颈集中在网络通信开销方面,缺乏优化空间.对GET操作来说,涉及SSD读取时,SSD延迟最高且占比显著.如图5所示,经测试,GET操作中的存储访问延迟整体占比可高达70%以上.
Fig.5 The latency analysis of a GET operation
图5 GET操作的延迟占比分析
参考上述性能特点,GET操作传输大消息时,SSD读操作与网络通信存在并行流水优化的空间.UKV系统将大消息数据分片处理,从而实现SSD读操作与网络传输交叠执行,如此并行流水来掩藏通信开销,大幅降低了涉及SSD读取的GET操作的整体延迟.如图6所示,在统一流水线中,每个数据分片由SSD读取以后,经由TCP/IP协议栈封包后交由网卡异步传输;异步网络传输发起后立即返回,并随之异步传输相应的标记位;再之后同步执行向SSD的下一数据分片读取.客户端逐片收到数据,该过程持续到客户端接收到最后一片数据分片.可见,网络传输中的协议栈处理仍然由CPU完成,交叠执行实际起始于网卡DMA传输.由于SSD访问延迟显著大于其他处理延迟,CPU处理协议栈的环节并不会拖慢整体流水效果.
Fig.6 The unified pipelining of networking and SSD I/O
图6 统一并行流水的优化方法
得益于全用户态、统一内存中转池的设计,UKV系统能够实现细粒度的流水线设计与调优,且性能干扰因素较少、流水线表现更加稳定.
本节详细介绍UKV系统的实现.
UKV的系统架构如图7所示,主要包括3部分:网络模块、存储模块与数据模块.网络模块负责用户态直接驱动网卡、发送或接收网络数据包、网络协议栈封装或解析等;存储模块负责用户态直接驱动SSD、请求与完成队列管理等;数据模块则主要负责基本的key-value逻辑与存储(例如Memcache接口、slab存储等)以及统一的控制平面、数据流水线、联合I/O调度等.
Fig.7 The architecture of the UKV system
图7 UKV的系统架构
UKV系统的服务端与客户端通过标准TCP/IP协议进行通信.UKV服务端内部是完全用户态的网络通信且支持内存-外存2层存储,对NVMe SSD的驱动与管理同样完全于用户态实现.UKV控制平面与数据平面分离且各自紧密整合网络与I/O,有助于屏蔽系统噪声、精简数据通路.
网络模块和存储模块分别负责完成用户级网络通信和用户级SSD访问,由统一控制平面和统一数据平面联合到一起.
数据模块主要包括网络管理模块、协议管理模块、key-value索引与存储模块、统一数据读写模块以及其他辅助模块.网络管理模块主要负责响应客户端建立连接并响应客户端请求,以及通过网络收发消息.协议管理模块主要负责按Memcache格式解析收到的网络请求以及封装准备发出的请求答复.数据管理模块主要负责数据区域的建立和管理.索引管理模块主要负责索引表的建立和管理.数据读写模块主要负责读写统一内存中转池,以及通过存储模块访问NVMe SSD.
2.2.1 网络管理模块
网络管理模块使用F-Stack提供的网络I/O事件通知机制,其底层基于DPDK用户级以太网卡驱动、用户级TCP/IP协议栈和kqueue I/O模型.
UKV系统启动时首先初始化网络I/O事件通知模型.然后初始化非阻塞的用户级监听套接字,绑定服务端的IP地址和端口号,并设置IP地址和端口号为可重用.随之封装监听套接字的读事件并加入通知模型.通知模型开始轮询监听,一旦收到向监听套接字的连接请求,就与客户端建立连接,并将已建立的非阻塞用户级套接字的读事件也加入通知模型中.通知模型继续轮询监听,当其中某个套接字收到消息后触发读事件并调用回调函数,此后执行数据读取、请求解析等后续操作.当其中某个套接字收到发送消息的请求后,则将该套接字的写事件加入到通知模型,监听到写事件触发后,调用回调函数并发送数据给客户端.
2.2.2 数据管理模块
数据管理模块负责建立和管理4个数据区域:内存数据区、SSD数据区、数据中转内存池、数据缓存区.
内存数据区和SSD数据区通过slab机制管理,主要用来存储key-value对数据,其方式与Fatcache类似,不过DRAM与SSD之间的数据置换采用了最近最少使用的策略.
数据中转内存池为预先分配的、供网卡收发与SSD读写中转的统一内存存储池,替代了传统操作系统机制下分离的内核网络缓冲区、内核存储缓冲区以及用户应用缓冲区.该内存池可于用户态直接访问且同时作为网络与SSD的DMA缓冲区,数据路径简化、无需额外数据拷贝.结合UKV系统,数据中转内存池又分为2部分:1)用于TCP/IP协议的解析和封装;2)用于Memcache协议的解析和封装.二者之间的数据格式转化不涉及上下文切换,开销较小、缓存效率高.
数据缓存区主要服务合并I/O优化.由于UKV采用run-to-completion模型,而且直接与存储设备硬件队列交互,并未利用现成的请求队列调度机制.数据缓存区将短时间内的I/O读请求缓存起来,若当前请求可以与已缓存请求合并,则直接读取缓存数据,避免对SSD的多次冗余访问.
2.2.3 索引管理模块
索引表存储于内存,访问延迟低,可以快速获取数据存储的具体位置,不同于传统存储系统需要频繁低效地访问外存.索引管理模块负责索引表的建立和维护,其原理机制与Fatcache类似,额外增加了用户I/O合并的缓存数据的索引.
本节从吞吐量和延迟的角度对UKV进行性能测试与分析.
测试采用2个物理节点:1)配备NVMe SSD,部署UKV或原生Memcached,作为服务端;2)部署客户端性能测试工具.2个节点通过万兆以太网卡相互连接.测试所采用的数据集由测试工具提供.
2个节点软硬件配置同构,具体如表1所示:
Table 1 Configuration of the Testbed Server
表1 测试节点的软硬件配置
ConfigurationDescriptionCPUIntel Xeon E5-2630 v3 2.4GHzMemoryMicron DDR4 128GiB 2133MHzNICIntel 82599ES, 10Gbps EthernetSSDIntel 750 NVMe SSD 400GBHDDSeagate ST91000640NS 7200RPMOSRedHat 6.3, Linux 3.10LibraryF-Stack 1.11, SPDK 16.06ToolTwemperf, Mutilate
测试与Twitter开源的Fatcache进行了对比,其上层与UKV的数据管理模型基本一致,但是底层基于传统的操作系统内核网络和存储机制,并且网络栈与存储栈互相分离.
测试主要对吞吐量与延迟进行对比分析.具体来说,吞吐量是指key-value系统在单位时间内处理请求的数量,是衡量服务器性能的重要指标,单位是QPS.吞吐量测试建立多个并发连接,并发起多次并发请求,统计服务器处理完所有请求所花费的时间,再计算得到吞吐量.延迟则是指客户端向服务器发出请求到收到答复的时间,对真实互联网服务而言,通常直接影响用户体验.延迟测试建立多个并发连接,每个连接每次只发出一个请求,收到答复后,发出下一个请求,如此反复;持续一段时间后,统计所有请求从发出到收到答复所花费的时间,忽略花费时间最多的5%请求,统计其他95%请求中花费最多的时间,得到p95延迟.
内存数据区的大小会对性能造成很大的影响,故而测试将分为内存充足和内存不足2种情况.设定内存充足时,内存数据区足够大,不会发生涉及SSD访问的操作;而内存不足时,配置中几乎每次GET操作都会访问SSD,完成网卡通信、应用空间、SSD读取的完整数据通路处理,从而体现用户级融合I/O的性能优势.
内存充足和内存不足2种情况的查询配置相同:客户端与服务端建立500个并发连接,发起至少250万次的SET请求和至少50万次的GET操作,统计得到平均吞吐量性能.
如图8所示,内存充足时,相比Fatcache,UKV的SET操作的吞吐量提高了31.87%~100%.数据长度较小时,吞吐量提高了90%以上;随着数据长度的增加,吞吐量提高的比例有所下降;在数据长度达到4 KB时,吞吐量提高比例仍然达到了31.87%.
Fig.8 The average throughput of SET operations with sufficient memory
图8 内存充足时SET操作的平均吞吐量
如图9所示,内存充足时,相比Fatcache,UKV的GET操作的吞吐量提高了21.62%~38.48%.在数据长度达到4 KB时,吞吐量提高了21.67%.
Fig.9 The average throughput of GET operations with sufficient memory
图9 内存充足时GET操作的平均吞吐量
如图10所示,内存不足时,UKV的SET操作的吞吐量提高了14.97%~97.78%.数据长度较小时,吞吐量提高可达90%以上;随着数据长度的增加,吞吐量提高的比例有所下降;在数据长度达到2 KB时,吞吐量仍然提高了40.22%;在数据长度达到4 KB时,吞吐量提高比例14.97%.
Fig.10 The average throughput of SET operations with insufficient memory
图10 内存不足时SET操作的平均吞吐量
如图11所示,内存不足时,UKV的GET操作的吞吐量提高了16.71%~32.48%.在数据长度达到4 KB时,吞吐量提高了32.48%.
Fig.11 The average throughput of GET operations with insufficient memory
图11 内存不足时GET操作的平均吞吐量
内存不足时,几乎每次GET操作都需要访问SSD,吞吐量大幅下降.50万次GET请求对服务器单SSD的访问压力较大,测试得到的平均吞吐量性能并不是服务器的最佳性能.通过保持500个并发连接,但是适当减少GET请求数量,可以测试得到最大吞吐量性能,如图12所示.再与Fatcache相比,UKV的GET操作的最大吞吐量提高了14.60%~51.81%.数据长度较小时,吞吐量提高了50%左右;随着数据长度的增加,吞吐量提高的比例有所下降;在数据长度达到2 KB时,吞吐量仍然提高了27.91%;在数据长度达到4 KB时,吞吐量提高比例为14.60%.可见,内存不足时,GET操作的吞吐能力受到SSD随机访问性能的限制,与内存充足时相比有一定下降.
Fig.12 The maximum throughput of GET operations with insufficient memory
图12 内存不足时GET操作的最大吞吐量
UKV的统一控制平面减少了中断处理和上下文切换、统一数据平面减少了数据拷贝,节省的CPU资源可用来处理key-value请求、简化的数据通路消除了冗余数据搬移,再结合统一流水、单一地址空间等的优化,从而提高了吞吐性能.
数据长度较小时,不同的数据长度对吞吐性能的影响不大,这是因为数据传输和拷贝的开销较小且差距不大,UKV系统体现出了显著的性能优势.
随着数据长度的增加,UKV的吞吐量提高的幅度逐渐下降.这是由于用户态TCP/IP协议栈处理、Memcache数据格式化等占用的CPU资源越来越多,网络传输、SSD访问的开销也越来越高,渐成影响性能的主导因素.
如图11所示,内存不足且GET操作密度较高时,吞吐量提高的比例没有明显的规律.并发请求数量负荷较高时,访存压力增加、吞吐量下降,且下降的程度具有不确定性.
内存充足时的SET或GET操作的延迟性能,与内存不足时的SET操作的延迟性能较为接近.这是由于SET操作访问SSD的频率很低,以网络通信与内存访问为主,与内存充足时的SET和GET操作的数据通路几乎一致.故而本节的延迟测试主要分析内存不足时的SET操作与GET操作.
内存不足时,客户端与服务端建立500个并发连接,每个连接每次只发出一个SET请求,收到答复后再执行下一个请求;如此持续60s统计得到延迟性能.如图13所示,相比Fatcache,UKV的SET操作的p95延迟降低了26.12%~40.90%.如图14所示,UKV的GET操作降低了15.10%~24.36%.
Fig.13 The p95 latency of SET operations with insufficient memory
图13 内存不足时SET操作的p95延迟
Fig.14 The p95 latency of GET operations with insufficient memory
图14 内存不足时GET操作的p95延迟
UKV的统一控制平面的设计避免了中断处理、上下文切换、冗余软件栈处理以及潜在的核间通信核与数据迁移等延迟开销,统一数据平面减少了额外的数据拷贝,从而降低了延迟.
随着数据长度的增加,SET操作的p95延迟降低的比例逐渐下降,但是GET操作的p95延迟降低的比例并未下降.因为SET操作的性能主要受网络传输影响,网络协议栈处理开销渐成主导,性能提升比例越低;而GET操作的性能瓶颈始终在SSD随机访问上,数据长度的影响相对较小.
本节主要介绍基于高性能I/O的key-value存储系统的相关研究工作.
传统基于DRAM的key-value系统的性能受限于内核网络栈,采用高性能网络技术取代开销过大的传统套接字通信机制是一种比较直接的优化手段.RDMA(remote direct memory access)是高性能通信技术的代表,其在科学计算领域已有了广泛的应用[10].Jose等人[11]基于RDMA优化Memcache与Thongprasit等人[12]基于用户级TCP/IP协议栈优化Redis是比较代表性的工作.
利用高性能非易失存储技术来改进key-value系统的访存性能并降低存储成本是热点优化方向.定制化方案例如Open-Channel SSD虽然能取得理想的效率,但成本较高.基于商品SSD设备并结合系统软件定制优化是性价比较高的方案.近来的NVMoF(NVMe over fabrics)技术虽然提供了易用的块接口,但仍然由操作系统内核提供支持,无法消除资源争用、线程调度等的弊端.DPDK与SPDK提供了基础的用户级驱动,暴露了最为底层的硬件接口,无法为应用直接利用,且二者相对独立,彼此没有适配或优化.
Guz等人[13]提出数据中心内计算节点利用NVMoF技术访问专用存储节点上的数据,并以RocksDB为例进行了性能测评,结果表明采用NVMoF时,访问本地与远程存储资源,性能没有明显差距.
IBM研究院的Trivedi等人[14]提出了一种软件I/O栈,取名FlashNet,将高性能RDMA网络与Flash SSD融合统一管理.基准测试性能中,与传统套接字与文件系统的服务器相比,IOPS提高了38.6%,访问延迟降低了43.5%.
Klimovic等人[15]设计了一种基于软件的Flash存储服务系统——ReFlex,收获了与本地Flash访问性能相媲美的远程Flash访问能力.当系统负载较低时,比本地SPDK访问相比,ReFlex的远程读写延迟仅增加了21 μs和20 μs,单CPU处理器核的ReFlex吞吐能力可以达到850 K的IOPS.
本文设计并实现了用户级融合I/O的高性能key-value存储系统,并完成了统一并行流水优化,有效提升了数据访问性能.本文采用用户态整合网络与I/O栈以及控制与数据平面分离的设计,保证高效的数据通路.每个平面内则紧密统一网络与存储,最大限度降低系统软件的管理控制开销.通过吞吐量和延迟的性能评测,用户级融合I/O能够有效提升了key-value存储系统性能.
随着单节点I/O密度的进一步提升,单CPU处理器核很可能无法满足下一代高速存储的需求.下一步工作主要面向多核控制平面,结合节点内互连拓扑,提高融合I/O的效率与可扩展性.
[1]Cisco Systems, Inc.Cisco visual networking index: Forecast and methodology[EB/OL].2015 [2017-07-31].http://www.cisco.com/c/en/us/solutions/collateral/service-provider/ip-ngn-ip-next-generation-network/white_paper_c11-481360.html
[2]Peter S, Li Jialin, Zhang I, et al.Arrakis: The operating system is the control plane[C] //Proc of the 11th USENIX Symp on Operating Systems Design and Implementation.Berkeley, CA: USENIX Association, 2014: 1-16
[3]Intel Software.Accelerate your NVMe drives with SPDK[EB/OL].(2016-09-30) [2017-10-02].https://software.intel.com/en-us/articles/accelerating-your-nvme-drives-with-spdk
[4]DPDK Project.DPDK: Data plane development kit[EB/OL].2012 [2017-07-31].https://www.dpdk.org/
[5]SPDK Community.SPDK-Storage performance development kit[EB/OL].2015 [2017-07-31].https://spdk.io/
[6]Twitter, Inc.Fatcache-Memcached on SSD[EB/OL].(2013-02-12) [2017-04-20].https://github.com/twitter/fatcache
[7]Memcached Organization.Memcached—A distributed memory object caching system[EB/OL].[2017-07-31].http://memcached.org
[8]Tencent Cloud Team.F-Stack|High performance network framework based on DPDK[EB/OL].(2017-04-14) [2017-07-31].http://www.f-stack.org
[9]An Zhongqi, Zhang Zhengyu, Li Qiang, et al.Optimizing the datapath for key-value middleware with NVMe SSDs over RDMA interconnects[C] //Proc of the 2017 IEEE Int Conf on Cluster Computing.Piscataway, NJ: IEEE, 2017: 582-586
[10]Li Qiang, Sun Ninghui, Huo Zhigang, et al.T-NBC: Transparent non-blocking MPI collective operations[J].Chinese Journal of Computers, 2011, 34(11): 2052-2063 (in Chinese)(李强, 孙凝晖, 霍志刚, 等.T-NBC: 透明的MPI非阻塞集合操作[J].计算机学报, 2011, 34(11): 2052-2063)
[11]Jose J, Subramoni H, Luo Miao, et al.Memcached design on high performance RDMA capable interconnects[C] //Proc of the 2011 Int Conf on Parallel Processing.Piscataway, NJ: IEEE, 2011: 743-752
[12]Thongprasit S, Takano R.Toward fast and scalable key-value stores based on user space TCP/IP stack[C] //Proc of the Asian Internet Engineering Conf.New York: ACM, 2015: 40-47
[13]Guz Z, Li H, Shayesteh A, et al.NVMe-over-fabrics performance characterization and the path to low-overhead flash disaggregation[C] //Proc of the 10th Int Systems and Storage Conf.New York: ACM, 2017: Article No.16
[14]Trivedi A, Ioannou N, Metzler B, et al.FlashNet: Flash/network stack co-design[C] //Proc of the 10th Int Systems and Storage Conf.New York: ACM, 2017: Article No.15
[15]Klimovic A, Litz H, Kozyrakis C, et al.ReFlex: Remote flash≈Local flash[C] //Proc of the 22nd Int Conf on Architectural Support for Programming Languages and Operating Systems.New York: ACM, 2017: 345-359