负载自适应的存储池数据重构策略*

2021-03-01 03:33魏登萍陈浩稳谢徐超高文强
计算机工程与科学 2021年2期
关键词:池中大块线程

魏登萍,陈浩稳,谢徐超,袁 远,高文强

(1.国防科技大学计算机学院,湖南 长沙 410073;2.北京忆恒创源科技有限公司,北京 100192)

1 引言

随着大数据时代的到来,各领域产生的数据呈指数级增长。以海量数据分析处理为基础的数据密集型应用对带宽、吞吐率等存储性能和数据可靠性提出了更高的要求,存储系统已经成为制约计算机系统性能提升的主要因素之一。

近年来,闪存(Flash)[1]、相变存储器PCM(Phase Change Memory)[2]、铁电随机存储器FRAM(Ferroelectric Random Access Memory)[3]、磁阻随机存储器MRAM(Magnetoresistive Random Access Memory)[4]、忆阻器RRAM(Resistive Random Access Memory)[5]等各种新型存储介质相继出现,为提升存储系统的性能提供了良好的机遇。基于闪存的固态盘SSD(Solid State Driver)因闪存存储介质具有较优的访问性能、更低的功耗和更好的工艺成熟度,已率先在大规模存储系统中广泛应用。针对应用对存储容量和性能不断增长的需求,研究者将独立磁盘冗余阵列RAID(Redundant Array of Independent Disks)[6]与固态盘结合,提出了全闪存阵列RAIS(Redundant Array of Independent SSDs)技术[7],将大量固态盘组织起来为上层应用提供稳定可靠的大容量、更高性能的数据存储访问能力,并提供系统级的数据保护能力。NetApp[8]、EMC[9]和PureStorage[10]等各大公司相继推出了全闪存存储产品,以满足各领域对高性能存储产品的需求。

基于RAID的存储系统,当一块磁盘出现故障时,需要通过数据重构操作恢复该故障盘的所有数据,并使阵列恢复正常工作状态,重构时间会随着故障硬盘容量的增大线性增加。在数据重构时,用户I/O和数据重构I/O混合在一起,竞争使用系统资源,导致上层应用性能急剧下降,重构时间变得更长,并加大了数据丢失风险。在重构过程中,恢复数据会写入热备盘中,而热备盘也会成为系统的性能瓶颈,使得重构性能无法随着硬盘数量的增加而提高。处于“攻击窗口”的重构期间[11],数据丢失风险加大,应用I/O访问的性能下降,重构效率对于系统的可靠性和性能都产生了重大影响,因此,如何在数据重构时尽可能地减少用户I/O请求的影响,成为基于RAIS的存储系统研究的重点之一。

针对上述RAIS存储系统中的数据重构问题,研究工作主要围绕数据布局和重构调度策略展开。一方面,设计更优的数据布局方案,减少数据重构时间。Wan等人[12]提出一种新的RAID结构,将RAID中的硬盘分为多个分区,利用其它分区创建子RAID,使得重构过程可以并发执行,加快重构速度。Google[13]则结合RAIS和虚拟化技术,在多个SSD之上建立虚拟存储池,在存储池上建立RAIS,通过动态地址映射建立RAIS到底层SSD的地址映射,将读写压力更均匀地分散在各个成员磁盘上,以加速I/O请求和重构操作。文献[14]对Declustered RAID系统中的数据布局方式进行了评价,结果显示Declustered RAID能够有效减少数据恢复时间。Zhang等人[15,16]提出一种叫作RAID+的RAID构建机制,该机制采用latin square结构来组织数据,让更多的硬盘参与数据服务和数据重构操作,以同步提高用户I/O和重构I/O的性能。另一方面,设计重构请求调度策略,在一定程度上均衡用户I/O和重构I/O的请求处理,提高系统性能。Tian等人[17]提出根据数据的访问频率确定重构请求顺序,经常访问的数据优先重构,提高了重构效率并减轻了重构对用户I/O请求的影响。Wu等人[18]提出了WordOut策略,在重构时将写请求和经常访问的读请求交给代理 RAID处理,以缩短重构时间。文献[19]针对固态盘垃圾回收操作对RAIS系统性能的影响,提出了垃圾回收操作引导的RAID实现系统GC-Steering,以提高RAIS系统的性能和可靠性。

本文设计实现了一个采用底层存储虚拟化的SSD存储池,叫作NV-BSP(NVMe Burst Storage Pool),将多块SSD盘的存储空间划分为更细粒度的大块,并利用RAIS技术在大量来自不同固态盘的大块上构建虚拟盘以供用户使用;由于虚拟盘的访问最终落在多块固态盘的并发访问上,对计算资源提出了更高的需求,设计了多核并发I/O处理架构,以提升I/O性能;提出了负载感知的I/O调度策略,在保证用户I/O服务质量的同时,尽量缩短重构时间,在系统出现故障后能快速恢复到正常状态。

2 支持多线程并发处理的存储池设计

2.1 存储池架构

Figure 1 Architecture of NV-BSP

基于存储虚拟化技术,本文设计实现了一个基于固态盘的存储池(简称NV-BSP),其架构如图1所示。所有SSD盘的存储空间被划分为固定大小的大块,并被池化到一个存储池中。存储池中维护了系统中所有的空闲大块,这些空闲大块通过资源分配器分配到RAID组中,并通过RAID技术构建一个具有数据保护能力的存储资源容器。资源分配算法采用随机的分配算法,根据各硬盘的裕量情况和磨损情况随机地从存储池中选取条带长度数量的硬盘,并从各个硬盘中选取一个大块,组成RAID组,使得每个存储盘上的资源均匀利用,且一个RAID组中的大块资源之间不存在相关性。根据容量需求,多个RAID组构成一个虚拟盘,通过块设备接口的方式对外提供服务。同一个虚拟盘中,每个RAID组的数据保护级别和容量相同;不同虚拟盘中的RAID组可以具有不同的数据保护级别和大块构成方式。

为避免一块SSD损坏时导致数据无法恢复,资源分配器在分配大块时,最多只为一个RAID组分配一个来自某个SSD的一个大块,保证一个RAID组内不存在2个来自同一个SSD的空闲大块。同时,为了保证用户I/O请求性能和数据重构性能能够随着硬盘数量扩展,在资源分配时需考虑大块的离散性,尽量均匀利用每个SSD盘上的大块存储资源。

假设要在4块容量为1 TB的SSD上创建存储池,大块容量设置为8 MB,并创建一个容量为24 GB的虚拟盘,数据保护级别设置为RAID5,且每个条带中具有3个数据单元。NV-BSP会根据要求的数据保护级别和条带中的数据单元数量,为每个RAID组分配4个容量为8 MB的大块,并构建RAID5,每个RAID组的数据容量为24 MB,则24 GB的虚拟盘需要构建1 024个RAID组。虚拟盘根据RAID组的组成顺序地从0开始编址,则每个逻辑地址LBA与虚拟盘中RAID组的编号RAID_index的映射关系定义为:

RAID_index(LBA)=LBA/Capactiy_R

(1)

其中,Capacity_R为虚拟盘中RAID组的容量。

2.2 多线程并发I/O处理

存储池I/O访问请求主要指对RAID组数据条带进行读写的I/O请求,主要分为用户I/O和内部I/O 2大类。用户I/O请求主要指上层应用对RAID组数据条带的访问请求;内部I/O请求主要指存储池内部触发的I/O请求,主要包括数据重构和数据迁移2大类。由上述存储池的架构可以看出,存储池的I/O请求对虚拟盘的访问最终转为对存储池中所有SSD的并发访问,再加上SSD的访问速度比传统磁盘更快,这就对存储池中的计算资源提出了更高的需求。为了使存储池的并发I/O处理能力能够充分发挥,NV-BSP将最大限度地利用CPU资源,为每个存储池分配多个CPU核心,以创建多个独有的I/O线程处理器,以并发处理用户I/O请求和内部I/O请求。

NV-BSP为每个虚拟盘中的每个RAID组分配一个I/O线程处理器,负责处理该RAID组所有的I/O请求和内部I/O请求。当虚拟盘中的RAID组个数大于I/O线程处理器个数时,可以将多个RAID组按照编址顺序均匀分配给一组I/O线程处理器。每个I/O线程处理器负责虚拟盘中一系列RAID组的访问处理。

假设存储池所分配的I/O线程处理器个数为IO_N,组成虚拟盘的RAID组个数为RAID_N。为了使I/O线程处理器的负载尽可能均衡,某个编号为RAID_index的RAID组与分配到的I/O线程处理器编号的映射关系定义为:

Thread(RAID_index)=RAID_index%IO_N

(2)

则0≤Thread(RAID_index)≤IO_N-1。

3 负载自适应的I/O调度策略

3.1 基于存储池的数据重构

当存储池中的一块磁盘出现故障或者掉电时,包含该故障盘中某个大块的RAID组的数据保护能力降级,需要进行数据重构以恢复正常工作状态。根据2.2节介绍,按照RAID组的编号,将RAID组按照其I/O线程处理器进行分组。如图2所示,每个I/O线程处理器负责处理m个RAID组,包含故障盘大块的RAID组用灰色表示,将会进行数据重构操作。用户I/O请求队列中有p个用户请求,重构I/O请求队列中有q个重构I/O请求,每个I/O线程处理器负责的RAID组集合中,每个RAID组都有若干个用户I/O请求和重构I/O请求。

Figure 2 Diagram of I/O thread processor request

当存储池触发数据重构操作时,会产生大量的对RAID组中条带的I/O读写操作。通常,存储池重构操作采用固定策略,如用户I/O模式策略、重构I/O模式策略和固定调度比例模式等。在用户I/O模式下,若有用户I/O请求,则延迟重构操作的执行,直到用户I/O执行完毕,这样将会加大再次发生大块失效时数据丢失的风险;在重构I/O模式下,出现故障盘时,立即执行数据重构操作。数据重构操作会占用大量的I/O带宽,耗时也较长,用户I/O需要等待重构操作完成后才能进行处理,这势必会影响用户I/O的服务质量;在固定调度比例策略模式下,根据调度比例,分别从用户I/O和重构I/O队列中调度对应数量的I/O请求进行处理,用户I/O和重构I/O可能造成各RAID组的负载不均衡,并竞争访问存储池中的SSD,影响用户I/O的服务质量和重构效率。

3.2 基于QoS的请求调度策略

基于存储池的动态冗余管理机制与传统RAIS相比,由于整个存储池中的固态盘都同时参与数据重构,因此相同数据容量的数据重构时间比传统RAIS的重构时间要少得多。由于存储池在向上层应用提供服务时,其用户I/O负载是动态变化的,假若以固定比例来调度用户I/O请求与重构I/O请求,则会影响用户I/O的服务质量和内部数据重构的进度。

针对上述问题,本文提出基于QoS的请求调度策略,根据用户I/O负载情况高效调度数据重构I/O请求与用户I/O请求,在尽量保证I/O服务质量的同时,保证数据重构操作能够尽快完成,不影响数据保护能力。

由于用户I/O负载是动态变化的,该调度策略根据用户I/O负载的情况,每隔一个单位时间段动态调整不同的调度比例,且调度比例随着时间的推移而动态变化。该策略将用户I/O请求与内部I/O请求的调度比例设置为多种不同的级别,以10%为步长,从10%增加到90%。调度比例为10%,表明在该时间段内,调度的用户I/O请求数量与内部I/O请求数量的比例为1∶9。如图3所示,在时间段1内,调度比例为30%;到了时间段2,用户I/O请求负载加重,则相应调高一级调度比例,为40%,依次类推。当然,在当前时间段里,若发现用户I/O请求负载比起前一个时间段的压力减小,则相应调低一级调度比例。

Figure 3 I/O scheduling strategy based on QoS

根据用户I/O负载的动态变化情况,确定当前时间段内用户I/O请求和重构I/O请求的调度比例,并根据调度比例分别从用户I/O队列和内部I/O请求队列中选取合适数量的请求进行调度处理。

3.3 负载感知的重构I/O调度策略

当存储池中出现故障盘时,会引起若干包含该故障盘大块的RAID组的数据重构操作。RAID组之间的数据重构操作执行的先后顺序对数据一致性无影响,且数据重构操作对延迟不敏感。为了使得重构I/O请求与用户I/O请求尽量减少访问冲突,使得调度的数据重构I/O请求与用户I/O请求尽量均衡地访问不同的硬盘,需要根据存储池中各个SSD的负载特征,确定重构I/O请求的调度优先级。

在一个时间段内,根据存储池中每个SSD硬盘的负载情况选择合适的重构请求,使重构请求尽量不与用户I/O请求竞争存储池中SSD的带宽,在不增加用户I/O请求延迟的情况下提高重构I/O带宽。由于用户I/O负载是动态变化的,因此需要在每个时间窗口内更新存储池中SSD的I/O负载情况,并由此确定重构I/O请求的调度优先级。

设存储池中包含的SSD集合为SSDs={D1,D2,D3,…,DM}(M为存储池包含的SSD个数),每个盘Dj(Dj∈SSDs,1≤j≤M)可划分为固定大小的多个大块,用BS(Dj)表示,即BS(Dj)={B1,B2,B3,…,BN}(N为Dj中包含的大块数量)。每个虚拟盘由多个RAID组的集合构成,即RAID={RAID1,RAID2,RAID3,…,RAIDK}(K为虚拟盘中包含的RAID组个数,由虚拟盘的容量和RAID组的容量确定)。每个RAID组包含P个大块,P由创建虚拟盘设定的数据条带单元和RAID级别确定,例如虚拟盘的数据条带单元数为4,RAID级别设置为RAID5,则虚拟盘中每个RAID组中的大块数量P为5。编号为index的RAID组包含P个大块,其集合表示成:

B(index)={B1,B2,…,BP}

(Bi∈BS(Dj),1≤i≤P,1≤j≤M)

(3)

RAID组中某大块Bi与底层SSD集合的映射由存储池中的资源分配器确定,定义为:

BD:Bi→Dj,1≤i≤P,1≤j≤M

(4)

编号为index的RAID组中大块来源的SSD集合定义为:

DS(index)={BD(B1),BD(B2),…,

BD(BP)},Bi∈B(index)

(5)

在当前时间窗口内,假定整个存储池中所有用户I/O请求集合为R={r1,r2,r3,…,rQ},每个用户I/O请求ri(1≤i≤Q)最终会以条带的方式访问存储池中的P个SSD。

由式(1),根据每个用户I/O请求ri(1≤i≤Q)访问的逻辑地址LBA(表示为ri.LBA)确定所访问的RAID组的编号为:

RAID_index(ri.LBA)=ri.LBA/Capacity_R

(6)

则该请求ri最终访问的SSD集合定义为:

D(rj)=DS(RAID_index(ri.LBA))

(7)

存储池中每个SSD与用户I/O请求ri之间的关系定义为:

Dj∈SSDs,1≤j≤M

(8)

存储池中每个SSD的负载定义为:

Dj∈SSDs,1≤j≤M

(9)

在一个时间段内,每个I/O线程处理器根据存储池中的每个SSD的负载确定重构I/O请求BR={b1,b2,b3,…,bL}中每个bi(1≤i≤L)的重构优先级。bi的重构优先级Pro(bi)定义为:

(10)

4 性能评价与分析

4.1 实验环境

实验硬件环境采用超微NVMe存储服务器,配置如下:2个Intel Xeon Gold 6128 3.4 GHz 6核CPU(支持超线程),196 GB内存,最大支持10个NVMe硬盘,配置8块Intel DC P4510系列2.0 TB NVMe硬盘。实验软件环境为:操作系统为CentOS 7.7,内核版本为4.19.46;NVMe存储池管理软件为NV-BSP。

4.2 实验结果

4.2.1 数据重构时间

为了评测基于存储池的多线程并发I/O处理的效果,创建了3类虚拟盘:(1)RAID(3+1,5 020 GB):由4块SSD组成的存储池,RAID组配置为3块数据盘和1块校验盘组成的RAID5,虚拟盘容量为存储池中所有可用空间容量5 020 GB;(2)RAID(7+1,11 714 GB):由8块盘组成的存储池,RAID组配置为7块数据盘和1块校验盘组成的RAID5,虚拟盘容量为整个存储池的可用空间容量11 714 GB;(3)RAID(7+1,5 020 GB):由8块盘组成的存储池,RAID组配置为7块数据盘和1块校验盘组成的RAID5,虚拟盘容量为5 020 GB。存储池设置了从1~24的不同I/O线程处理器数量。

Figure 4 Time of data reconstruction

图4列出了在一块物理盘掉电或出现故障时,在没有用户I/O情况下不同配置的虚拟盘数据重构时间。整体来看,不同配置的虚拟盘的数据重构时间都随着I/O线程处理器数量的增加而降低,说明增加存储池中的I/O线程处理器数量能够增加虚拟盘中各个RAID组进行数据重构的并发性,从而降低数据重构时间。在4块盘组成的存储池中,当I/O线程处理器数量大于4时,虚拟盘RAID(3+1,5 020 GB)的重构时间基本趋于平稳,也就是说在没有用户I/O的情况下,4个I/O线程处理器能够较好地处理虚拟盘RAID(3+1,5 020 GB)的数据重构,再增加I/O线程处理器数量,数据重构时间不会显著降低。在虚拟盘RAID(3+1,5 020 GB)中,每个RAID组都来自存储池中的4块硬盘,每个I/O线程处理器负责的数据重构操作会竞争访问存储池中的4块硬盘。当I/O线程处理器数不断增加时,整个虚拟盘的重构效率会受限于硬盘的访问性能,这时增加I/O线程处理器已不能显著缩短数据重构时间,还会增加计算资源的开销。同理,在8块盘组成的存储池中,不论虚拟盘容量的大小,在没有用户I/O请求的情况下,当I/O线程处理器数量达到8时,重构时间基本趋于平稳,此时增加I/O线程处理器数量已不能显著提高重构性能。

4.2.2 负载自适应的I/O调度策略

为了验证负载自适应的请求调度策略,在NV-BSP中创建了一个由4块SSD组成的存储池,RAID组配置为2块数据盘和1块校验盘组成的RAID5,虚拟盘容量为1 000 GB。通过运行FIO测试程序(job数量为1)模拟用户I/O负载,在FIO运行过程中,每隔1 min调整用户I/O和数据重构I/O的调用比例,记录用户I/O带宽和重构I/O带宽。调整步骤如下所示:

(1)在FIO程序运行1 min后,将某块存储池中的硬盘掉电,存储池启动重构操作,这时用户I/O和重构I/O的比例为9∶1,即用户I/O占90%;

(2)在FIO程序运行2 min后,调整用户I/O和重构I/O比例为1∶4,即用户I/O占20%;

(3)在FIO程序运行3 min后,调整用户I/O和重构I/O比例为9∶1,即用户I/O占90%;

(4)在FIO程序运行4 min后,终止FIO程序运行,调低用户I/O和重构I/O比例直到数据重构完成。

图5展示了用户I/O带宽和重构I/O带宽随着用户I/O和重构I/O数量比例的调整而变化的情况。从图5可以看出,当存储池触发重构操作后,由于用户I/O和重构I/O的调度比例为9∶1,用户I/O的性能基本没受影响,约为2.0 GB/s。当用户I/O和重构I/O的调度比例调整为1∶4以后,在当前时间段按照该比例调度一定数量的用户I/O请求和重构I/O请求进入待执行队列,由于待执行队列中的用户I/O请求数量急剧变少,而重构I/O请求数量增加,因此用户I/O的带宽从2.0 GB/s左右急剧下降到620 MB/s左右,重构I/O的性能从200 MB/s左右快速上升到1.2 GB/s左右。当用户I/O和重构I/O的调度比例重新调整为9∶1时,待执行队列中的用户I/O数量急剧增多,因此用户I/O请求的带宽又快速上升。当用户I/O请求处理完毕时,调低用户I/O和重构I/O比例,重构性能又随之上升。整个过程展示了NV-BSP支持随着用户负载的变化而调节用户I/O和重构I/O的调度比例。

Figure 5 Bandwidth of I/O requests

5 结束语

针对传统RAIS系统数据重构时间长,且重构时影响用户I/O性能的问题,本文设计实现了一种多线程并发处理的存储池,能够并发处理用户I/O和重构I/O,提高存储池的访问性能。基于该存储池提出一种负载自适应的I/O调度策略,根据用户负载的变化动态调整用户I/O请求和重构I/O请求的调度比例,保证用户I/O服务质量的同时,提升数据重构效率。实验结果表明,基于存储池的多线程并发I/O处理架构能够有效减少数据重构时间,负载自适应的I/O调度策略能够支持用户I/O和重构I/O调度比例的动态变化,在保证用户I/O请求服务质量的同时,尽量保证重构I/O请求与用户I/O请求的并行执行,提高重构效率。下一步工作将围绕存储池的全局磨损均衡、负载特征的自适应优化等方面展开,以完善和优化NV-BSP的功能和性能。

猜你喜欢
池中大块线程
基于国产化环境的线程池模型研究与实现
池中景象
老伴
浅谈linux多线程协作
V先生的幻想世界
用大块肉做丸子
Zr基大块非晶合金低速切削性能试验研究
可控挤入复合膏浆防渗灌浆技术在大块径漂卵石层防渗处理工程中的应用
么移动中间件线程池并发机制优化改进