APP下载

一种可动态配置的分布式内存池缓存一致性机制

2023-09-22段卓辉刘海坤赵金玮刘一航廖小飞

计算机研究与发展 2023年9期
关键词:内存一致性客户端

段卓辉 刘海坤 赵金玮 刘一航 廖小飞 金 海

(大数据技术与系统国家地方联合工程研究中心(华中科技大学) 武汉 430074)

(服务计算技术与系统教育部重点实验室(华中科技大学) 武汉 430074)

(集群与网格计算湖北省重点实验室(华中科技大学)武汉 430074)

(华中科技大学计算机科学与技术学院 武汉 430074)

(zhduan@hust.edu.cn)

随着大数据、云计算、人工智能等技术的不断发展,计算机需要存储和处理的数据呈指数级增长.传统的单机节点已经无法满足这些应用对计算资源和存储资源的需求,分布式内存系统成为解决扩展性问题的一个有效途径[1].随着新型非易失性存储器(non-volatile memory,NVM)[2-3]和远程直接内存访问(remote direct memory access,RDMA)技术在数据中心的广泛应用,为分布式内存系统的设计带来了新的契机.基于NVM/DRAM(dynamic random access memory)异构内存和RDMA 技术的分布式内存系统已成为国际研究的热点[4-6].

为了提高分布式内存系统的性能,数据往往会被客户端缓存以加速远程读写操作,从而减轻服务器端的访存压力[7].然而,缓存机制的引入也会带来分布式系统中缓存不一致的问题[8].当一个客户端缓存了共享的存储对象后,另一个客户端执行对该共享存储对象的更新操作就会导致缓存不一致的问题.因此,在分布式环境中,当存储对象的源节点更新时,需要确保缓存的副本也被更新.然而,保证缓存一致性往往带来较大的性能开销.分布式系统不仅需要同步节点之间的缓存副本[9],还需要降低确保缓存一致性所带来的开销,否则使用缓存带来的性能提升将会被抵消.

新兴的RDMA 技术使得远端内存的高速访问成为可能.在高速Infiniband(IB)网络下,远端节点的读写延迟能接近本地读写延迟[10].直接通过网络进行远程读写操作是解决缓存一致性开销问题的一种直接方法[7].

表1 展示了本地DRAM 和RDMA 访问远端的性能对比.QDR,FDR,EDR 和HDR 是不同规格的IB 网络.即使使用了RDMA 技术,通常情况下远程读写的延迟仍然比直接读写本地DRAM 要高[8].因此,分布式系统不能简单地舍弃客户端缓存,设计和实现缓存一致性机制在分布式异构内存系统中仍然至关重要.由于确保缓存一致性必然会带来一定的开销,因此高效的分布式缓存一致性算法必须权衡缓存带来的性能提升和确保缓存一致性所带来的开销,以达到系统在保证缓存一致性的前提下,依然能够比无客户端缓存的情况下获得更高的性能.

Table 1 Performance Comparison of Local DRAM and RDMA表1 本地DRAM 和RDMA 性能对比

传统的缓存一致性解决方案有3 种不同的方法.首先,基于时间戳的租约机制[11]是一种常用的保证共享对象并发访问一致性的方法.该机制在租约期内授予缓存数据的客户端对相应数据的读写权力.基于租约的缓存一致性机制需要考虑许多使用问题,例如时间参数的平衡问题[12].分布式系统应该慎重考虑颁发的租约时间长短.如果租约时间过长,会影响系统同步的效率,使其他节点等待时间过长;相反,如果租约时间过短,往往需要频繁进行续约,增加续约的通信开销,导致整体分布式系统效率降低.此外,时钟同步也是需要考虑的因素[13].由于,不同节点的时间可能存在误差,基于租约的一致性机制就会出现问题.另外,还需要考虑单节点故障问题.租约机制依赖于某个服务器节点颁发的租约时间戳,如果该节点出现故障,将会影响整个系统的使用,导致系统故障.

其次,基于目录的缓存一致性保证机制多用于数据更新比较频繁的场景[14].该机制需要维护一个全局公共目录,目录中保存了缓存的元数据信息,包括缓存是否为脏数据等.当客户端读取数据时,需要查询相应节点的目录以确定缓存的状态,从而获取缓存是否可用的信息.当某个客户端节点更新数据时,需要更新缓存的目录状态,以供其他节点查询.基于目录的缓存一致性保证机制也存在一些问题.一方面,目录的维护需要额外的存储空间,增加了存储开销;另一方面,对于读取数据的节点来说,每次操作都需要查询远端目录来确定缓存状态,增加了时间开销,降低了系统效率[15].

最后,基于广播方式实现的缓存一致性保证机制多用于数据读操作多、更新不频繁的场景[16].在RDMA 通信环境下,这种机制面临着新的挑战.当一个客户端节点需要更新数据时,需要向其他共享节点广播相应的信息.当其他节点监听到更新信息后,将当前缓存数据标记为不可用,并在后续阶段进行刷新.基于广播方式的一致性保证机制具有较高的效率.当某个客户端需要读取数据时,在缓存中存在此数据的情况下,只需要进行本地缓存读取即可.然而,在RDMA 网络中,广播通信是不可靠的,而在RDMA网络中建立可靠的广播机制成本较高,而且该广播机制可能会造成比较严重的网络拥塞问题[8].

综上所述,传统的缓存一致性保证机制各有利弊.在实际应用中,需要对这些方法进行改进和完善,并根据不同情况决定使用哪些缓存一致性保证机制.本文基于NVM 和RDMA 技术,试图在分布式异构内存池中实现一种全新的缓存一致性保证机制,为大数据时代的分布式应用提供更高效的分布式内存系统.

本文面向分布式异构内存池系统,提出了一种目录和广播相结合的缓存一致性保证机制,并且可在运行时动态切换缓存一致性保证机制,以有效提升缓存一致性保证的效率.我们通过四象限矩阵分析方法对每个数据块进行访问模式的判定分析,并将其转换为适合的缓存一致性保证策略,从而提高了数据同步效率和性能优势.实验结果表明,相对于使用单一基于目录或基于广播的缓存一致性保证机制,采用可动态转换的缓存一致性保证机制的分布式异构内存池系统平均读写性能分别提升了32.31%和31.20%.此外,在客户端数量不断增加的情况下,可动态转换的缓存一致性保证机制表现出良好的扩展性能.

1 国内外研究现状

在分布式环境中,当多个客户端共享同一存储对象时,分布式系统往往采用租约、目录或广播等缓存一致性保证机制来确保客户端的缓存副本与服务器的存储数据版本保持一致.近年来,国内外对于缓存一致性保证机制的研究主要集中在对传统机制的实现和改进上,同时也涌现出一些利用新型硬件或软件加速缓存一致性机制的研究成果.

1)多核处理器的缓存一致性协议.在多核系统中,缓存一致性问题是普遍存在的.当多个缓存同时访问同一块数据时,读写操作可能导致缓存的不一致性,这个问题在现代多核处理器中尤为突出.为了提高CPU 对内存的访问速度,多级缓存被引入到CPU 和内存之间.每个多核处理器的核心都有自己的缓存,当进行读写操作时就会引发缓存不一致性的问题.MESI(modified exclusive shared invalid)协议是一种广泛使用的缓存一致性协议[17-19],它将缓存状态划分为4 种,并通过读写事件相互转换.在进行写操作之前,必须获得独占权限,在进行读操作之前至少要保证是共享状态.MESI 协议本身是基于MSI 协议的发展而来,MSI 协议只有3 种状态,缺少了独占状态E.此外,还有许多扩展的协议基于MESI,例如加入了O 状态的MOESI 协议[20-21],其中O 状态表示所属状态,类似于E 状态,但该状态允许共享状态为脏的缓存行而无需写回内存.

多核系统中的缓存一致性协议MESI 本质上是一种基于监听的协议,各个处理器除了要处理自己的缓存,还要监听其它处理器的活动,这与分布式下基于广播的协议的原理类似.在分布式异构内存池系统中,服务器在基于广播的机制下也要监听客户端的缓存状态.此外,MESI 协议对缓存的4 种状态设计和触发事件导致的状态转换对于分布式内存池中缓存状态的设计也有一定的借鉴意义.

2)分布式系统的缓存一致性保证机制.在分布式存储系统中,确保缓存一致性的机制旨在保持缓存副本与服务器中存储的数据一致.因此,当对缓存数据或存储数据进行更新时,必须确保这些修改被同步到缓存的共享节点.

基于时间的租赁机制通过服务器向客户端颁发锁来实现数据一致性保证,但面临单节点故障和控制租约时间的参数问题.以色列研究人员提出了自适应租约[22],采用优化的租约机制,对不同类型的数据对象采用不同的租约,从而减少了网络延迟.为了解决单节点故障问题,来自加州大学洛杉矶分校的研究人员提出了Paxos 协议[23],通过多轮投票确定数据的一致性节点.在此基础上,微软研究人员对Paxos进一步优化[24-25].来自国防科技大学的研究人员提出了DCC 协议[26],结合了优化的Lease 和Fast-Paxos机制,通过Paxos 算法选举主节点,解决了单节点故障问题,并引入同步组的概念,使组内节点可以直接访问数据,并定义了确保数据最终一致性的数据写回过程.麻省理工大学的研究人员提出了逻辑租约技术[19],通过动态调整操作顺序以减少冲突的发生,从而提升分布式共享并行系统的扩展性和性能.逻辑租约技术结合了物理上和逻辑上的时间,形成了一种新的时间方式,更加灵活高效.

对于基于目录的机制来实现缓存一致性保证方案,系统需要维护一个全局目录,并通常需要一个元数据服务器节点.来自新加坡国立大学的研究人员提出的GAM 系统采用目录方式保持缓存一致性[6],将数据节点分为home 节点、remote 节点、request 节点和sharing 节点、owner 节点5 种类型,缓存节点分为Shared、Unshared 和Dirty 这3 种类型.不同的读写操作会导致状态之间的转换,最终实现了系统的缓存一致性保证机制,并对该机制下的系统进行了扩展性、局部性和延迟等方面的测试.新加坡国立大学和微软的研究人员合作提出的Pegasus 系统通过目录方式保证缓存一致性[27],利用可编程交换机来平衡存储服务器之间的负载,改进了基于目录的缓存一致性协议,仅在交换机数据平面中存储和转发元数据.以色列研究人员提出了COMBINE[28],这是一种基于目录的共享对象一致性协议,利用覆盖树数据结构,将系统节点作为覆盖树的叶子节点,将通过同一节点的请求合并在一起.COMBINE 利用覆盖树提高了最近邻搜索的效率,并减少了竞争,将服务请求的成本与覆盖树中请求节点和服务节点之间的最短路径成本关联起来.

基于监听广播的缓存一致性保证机制是一种高效的机制.在这种机制下,某个节点的读写操作会被广播给其他节点,不同节点中的缓存控制器会进行相同的处理操作,以确保在接收到相同广播后不同节点处于相同的状态,最终实现一致性[29].相比基于目录的缓存一致性保证机制,基于广播的机制不需要引入和维护目录,更加简单.此外,基于广播的机制不需要像基于目录的一致性保证机制那样传递大量的控制消息.然而,在大规模系统中,基于广播的机制在带宽和延迟等性能方面通常较差,因此只适用于小规模的分布式系统.来自上海交通大学的研究人员在RDMA 网络下实现了基于广播的分布式共享内存[30],对读请求处理和写请求处理进行了适应性设计和实现,并确保不同缓存控制器对读写请求的顺序相对一致性,最终测试表明,与传统分布式系统相比,其性能有显著提升.

3)混合的缓存一致性保证机制.为了提高一致性保证机制的效率,现有研究采用了混合缓存一致性机制,该机制能够进一步减小网络开销.克莱门森大学研究人员在其研究中提出了一种混合的缓存一致性保证机制[31],其结合了更新传播和失效策略.当对目标存储资源进行读写访问时,根据系统设计的策略,决定采用更新传播或失效策略.类似地,印度学者[19]也提出了类似的算法,该策略结合了传播和失效2 种策略以实现强一致性.对于写更新操作,该算法首先执行写的无效操作,然后在节点访问该存储资源之前更新缓存副本.这种策略显著减少了存储资源的访问延迟.这些缓存一致性保证机制都是结合了更新传播和失效策略,类似于直接广播模式和缓存副本失效模式,以实现一致性.

上述机制都是在元数据服务器节点上进行的,当多个节点进行写入时,会增加元数据服务器的负担.因此,一些研究提出同时利用客户端来确保存储系统的数据一致性.例如,来自西南大学的研究人员提出了一种自适应的细粒度缓存更新策略[5],将缓存一致性的更新操作移至客户端节点,针对不同的存储资源,该自适应策略结合应用的访问行为,采用不同的缓存一致性更新策略.这种自适应的混合缓存一致性保证机制显著降低了系统的存储资源访问延迟.另外,印度学者提出了一种基于自适应目录的缓存一致性模型[32],该模型能够显著优化分布式应用中的网络带宽.该工作在分层设计的分布式系统中实现了基于目录的缓存一致性模型,并添加了自适应特性以优化该模型,实验证明相比非自适应策略,自适应策略在性能上有很大改善和提升.

除了对传统机制的实现和改进,还有研究利用新的硬件加速缓存一致性.例如,清华大学的研究人员提出的Concordia 系统利用可编程交换机加速缓存一致性协议[33].该系统的核心是FLOWCC,一种写无效协议,该协议在交换机和服务器之间划分一致性责任,通过序列化冲突请求并通过锁定检查转发管道,并将它们多播到正确的缓存代理.

综上所述,缓存一致性的保证机制本质上是通过各种方式通知缓存了相同数据副本的节点,以实现各节点的缓存数据一致性.目前对缓存一致性保证机制的研究主要集中在对传统机制的适应性实现和改进,或者将多种机制混合以实现更好的缓存一致性保证机制,以降低系统的远程访问延迟.然而,缓存一致性协议的性能很大程度取决于协议与当前访问模式和行为的匹配程度.对于整体系统的访存行为的预测往往存在很大的不确定性,这就要求缓存一致性协议能够灵活地根据当前系统状态进行切换.传统的缓存一致性协议不能很好地适配动态变化的应用需求,因此亟需一种可动态配置的缓存一致性保证机制来适配不同应用动态变化的访存特征.

2 动态转换的缓存一致性保证机制的设计

本文面向分布式异构内存池系统,设计并实现了可动态转换的混合缓存一致性保证机制.首先,我们实现了分布式异构内存池的多客户端共享机制和客户端缓存机制.然后,设计并实现了可动态转换的混合缓存一致性保证机制.该机制根据应用的不同读写访问特征,提供相应的缓存一致性保证策略,以降低缓存一致性保证机制的开销,提高使用客户端缓存时的系统性能.分布式异构内存池系统的整体架构如图1 所示,采用客户端/服务器模型,为客户端提供远程内存资源.客户端节点通过DRAM 实现了缓存模块.客户端维护缓存目录条目,其中保存了每个缓存使用的缓存策略.服务器端同样维护存储对象的目录条目,其中将每个客户端的缓存信息作为一个节点串成链表.该系统架构为实现我们提出的混合缓存一致性保证机制奠定了基础.系统主要分为3 个功能模块,即分布式异构内存池中多客户端共享读写机制、混合的缓存一致性保证机制以及缓存一致性保证策略的动态转换机制,下面分别进行详细介绍.

Fig.1 The system architecture of distributed heterogeneous memory pool图1 分布式异构内存池系统架构

2.1 分布式异构内存池的多客户端共享读写机制

分布式异构内存池中多客户端共享读写机制的实现原理如图2 所示.我们在服务器端维护一个哈希表,其中键为唯一值ID,值为内存资源的全局地址和内存注册信息.为了实现多客户端共享读写,我们为客户端应用提供了函数接口.当客户端调用接口申请远端内存资源时,需要提供一个唯一的ID 值.服务器收到请求后,首先在哈希表中根据ID 值进行查找.如果没有查找结果,则说明该请求是非共享的,即简单的申请远程内存资源.服务器会检查自身的NVM 资源是否足够分配,并将分配的内存注册信息和生成的全局地址返回给客户端.同时,服务器需要将该ID 作为键,将该内存资源的全局地址和内存注册信息作为值插入到服务器端的哈希表中.如果根据ID 值查找到了结果,说明该请求是对已共享的远程内存资源的访问,此时无需进行新的NVM 内存资源分配,直接将查找到的内存资源的全局地址和内存注册信息返回给客户端即可.

Fig.2 The implementation principle of object sharing mechanism图2 对象共享机制实现原理

当使用RDMA 单边原语Read/Write 进行操作时,需要使用相应的内存注册信息.当申请内存的时候,由于客户端在初始节点就已经进行了内存的预申请和分配,客户端的共享内存管理程序直接返回一个地址映射信息,并向在服务器节点端标记当前内存已被共享.因此,客户端节点获得同一个NVM 内存资源的内存注册信息,从而实现多客户端共享该远程内存资源.由于共享接口的请求需要由客户端发起,并需要服务器进行处理,因此设计中采用了RDMA双边原语Send/Recv 来进行通信.当内存资源不够的时候,客户端共享内存管理程序无法找到空余的地址映射表,直接返回OOM 错误,该内存申请请求由于超过系统内存容量而失败.

此外,当多个客户端对共享内存进行同时写入操作时可能会出现并发问题.为了避免这种情况,服务器的目录中增加了写标志位.当有一个客户端对共享内存进行写入访问时,将写标志位置为真,从而阻止其他客户端同时进行写入操作,避免系统出现问题.

2.2 基于目录和基于广播的缓存一致性保证机制

为了满足不同应用的访问模式需求,我们采用了一种混合的缓存一致性保证机制.该机制依赖于服务器和客户端中目录信息的设计,并根据不同策略采取相应的读写处理方式.

当使用基于目录实现的缓存一致性保证机制时,在读取远程客户端数据时,首先要查询目录,并根据缓存是否脏决定是进行远程读取还是读取缓存.在进行写操作时,在数据写入服务器后,需要更新服务器上相应缓存的脏标志位.当采用基于广播实现的缓存一致性机制时,可以直接从客户端的缓存读取数据,而在进行写操作时,写入服务器后需要广播通知其他客户端更新缓存.我们实现了这2 种机制的混合应用,并且客户端和服务器共同维护缓存一致性.

混合缓存一致性保证机制的实现依赖于分布式内存共享系统中服务器的目录和客户端的缓存设计.服务器端的目录结构,其中每个目录项包括唯一ID、NVM 内存注册信息以及特殊的链表节点.链表节点记录了缓存该内存对象的每个客户端的信息,包括采用的缓存一致性保证机制、缓存脏位和缓存的DRAM 内存注册信息.客户端的缓存采用LRU 缓存策略实现,并使用双向哈希链表进行管理.哈希表的键是全局唯一地址,其值包含缓存的DRAM 信息、缓存采用的一致性保证机制以及读写次数计数等信息.如果缓存被淘汰,客户端需要向服务器发起请求以更新相应的目录,因此我们采用RDMA Send/Recv进行设计.

我们实现了客户端可调用的上层应用读写接口,通过这些接口实现了缓存一致性保证机制.首先,客户端发起读请求,该请求被封装为读工作请求并交由工作处理器处理.在识别为读请求后,工作处理器将其交给专门的处理器处理.然后,客户端根据LRU缓存策略判断是否命中缓存.如果未命中,则进行普通的RDMA 读操作,并将缓存目录中的脏位设置为非脏.最后,增加读计数并按照LRU 策略更新缓存.如果命中缓存,则判断目录中缓存采用的一致性保证策略.如果是广播机制,则无需进行远程读取,直接读取客户端缓存即可;如果是目录机制,则使用RDMA 双边原语发送查询脏位的请求,并由服务器进行回应.当缓存非脏时,可以直接在本地客户端缓存中读取数据;当缓存为脏时,需要进行远程RDMA读取,并进行相应的后续处理.

对于需要修改共享内存的客户端应用,可以调用写接口.首先,客户端发起写请求,该请求被封装为写工作请求并交由工作处理器处理.在识别为写请求后,工作处理器将其交给专门的处理器处理.然后,调用RDMA 写操作进行远程存储资源的更新,客户端发送请求刷新其他客户端的缓存.当服务器收到刷新缓存的请求后,根据ID 找到相应的内存对象,根据不同的链表节点采取不同的措施,根据其缓存一致性保证策略进行处理.如果是广播策略,服务器需要调用RDMA 写操作更新缓存;如果是目录策略,只需修改链表节点中的脏位.最后,客户端在完成写操作后,增加写计数并利用LRU 策略更新缓存.

LRU 缓存更新算法是一种简单且高效的缓存更新算法,每次将最新访问的对象放在缓存双链表的头部,确保对象不被淘汰.在我们的系统中,由各个客户端进行LRU 缓存更新.由于写接口设计中,采用广播实现的缓存一致性保证机制需要服务器对远程缓存进行RDMA 写操作,因此服务器端需要记录客户端DRAM 缓存的内存注册信息.每次进行缓存更新时,需要通知服务器有关新加入缓存和删除失效缓存的信息.对于新加入的缓存,需要向服务器发送缓存的内存注册信息,以在服务器目录中添加相应的链表节点.对于删除失效的缓存,需要通知服务器从链表中删除相应的客户端缓存信息.因此,系统设计了相应的消息类型,并使用RDMA Send/Recv 进行与服务器的目录保持一致的更新通信.

2.3 缓存一致性保证策略的动态转换机制

经过2.1~2.2 节的设计,分布式异构内存池系统已经具备了缓存一致性保证机制.但我们需要考虑如何进行缓存一致性保证策略之间的转换.首先,系统需要分析应用何时需要何种缓存一致性保证机制.不同应用或同一应用在不同运行节点的主要访问模式是不同的,有的应用主要是读,而有的应用主要是写.

对于目录实现的缓存一致性保证机制,每次在客户端进行读时需要到服务器查询目录的脏位置,而在写时不需要逐个更新客户端缓存,只需要修改服务器目录的脏位置,因此较为适合写比较多的访问模式.对于广播实现的缓存一致性保证机制,每次在客户端进行写时,在进行写之后需要逐个更新相应客户端的缓存,而在读时可以直接进行客户端缓存读,不需要去远程查询服务器目录,因此适合读比较多的访问模式.综上所述,系统需要统计每个共享内存对象的读写次数,从而分析该应用的访问模式是写主要还是读主要的.

在客户端共享对象的缓存目录中,可以通过读写计数得到一个向量(Wi,Ri),其中i表示某个共享对象,Wi表示该共享对象的写次数,Ri表示该共享对象的读次数.通过计算客户端全部共享对象的平均值同样可以得到另外一组向量(W*,R*),其中W*表示该客户端的所有共享对象的写次数平均值,R*表示该客户端的所有共享对象的读次数平均值.为了减小个别值的影响,采取缩尾均值法去计算平均值.写次数缩尾均值的计算方式如式(1)所示,读次数的缩尾均值与写次数类似.式(1)中Wnα+1~Wn-nα表示将写次数进行从小到大排序后的结果,α表示缩尾系数,n表示写次数,其计算方法即去掉的数据个数除以数据总个数,缩尾均值即在计算平均值时去掉若干个最大的值和若干个最小的值,最后得到的平均值结果会减小个别极端数据的影响.

根据读次数和写次数的向量(Wi,Ri)和(W*,R*)组成的2×2 矩阵,我们采用矩阵分析法来进行应用访问模式的判断和分类.根据读次数和写次数的多少,可以将应用的访问模式分为4 类:

1)当Wi

2)当WiR*时,属于读负载多的状态,应用此时属于读多写少的访问模式,因此采取基于广播的缓存一致性保证机制.在此情况下系统可以将过多远程读转化为本地的缓存读,从而提升系统的性能.

3)当Wi>W*但Ri

4)当Wi>W*且Ri>R*时,说明应用此时处于I/O 密集的阶段,应用对数据对象的读写访问都比较多,此时服务器的负担较重,因此默认采取基于目录的缓存一致性保证机制.该机制下对于过多的读请求可以由客户端查询目录后进行本地的缓存读;而对于过多的写请求,服务器不用进行过多的广播刷新,只需要修改服务器上的目录信息,从而减轻服务器的负担.

综上所述,利用2×2 矩阵可进行应用访问模式的分析判定,并为不同的数据采用不同的缓存一致性保证机制.1)和4)两种情况,分别代表低访问和密集访问的模式,系统在判定后,默认保持之前的缓存一致性保证策略.这2 种情况下,2 种缓存一致性保证策略对性能影响不大.对于基于目录的缓存一致性保证机制和基于广播的缓存一致性保证机制,其分别适用于写操作较多和读操作较多的模式.在低访问和密集访问的模式下,这2 种机制各有利弊,因此性能改变不大,默认保持之前的缓存一致性保证机制.

缓存一致性保证机制的转换应在客户端进行,但是当策略进行转变时需要通知相应服务器,因此需要使用RDMA Send/Recv 来设计实现相关功能.利用客户端的缓存目录中的读写次数构建矩阵,并利用以上分析方法进行计算决策,得到需要转换的缓存一致性策略.如果需要发送改变,则还需要通知服务器进行相应修改,以保证目录的一致性.为了保证各个机制的正确性,还需要重新刷新缓存.具体来说,如果从广播策略变为目录策略,由于广播策略可保证当前客户端缓存是最新的,因此只需要将服务器端脏位置更新为非脏即可.如果从目录策略变为广播策略,由于目录策略下不能保证客户端缓存是最新的,因此需要在数据写状态为脏的情况下重新刷新其缓存,以确保在广播策略下的正确性.

3 实验测试与结果分析

3.1 实验环境

本文的所有实验都在真实的硬件环境中进行.客户端缓存模块使用DRAM 内存,而服务器采用DRAM 和NVM 混合内存.在每个服务器节点上,NVM和DRAM 都被配置为NUMA 架构进行分配.我们在4 台服务器上进行性能测试,这些服务器均配置了NVM 和Infiniband RDMA 网卡.每台机器的具体硬件配置如表2 所示.NVM 是Intel 公司推出的Optane DCPMM,该存储器与传统DRAM 的通道接口一致,可以直接插入主板的内存插槽.实验中的NVM 和DRAM 均被配置为NUMA 架构,即每个存储资源和CPU 核心都被分配给不同的节点.用于测试的服务器都通过IB 网络进行RDMA 通信.

Table 2 Server Hardware Configuration表2 服务器硬件配置

为了测试系统在加入客户端缓存机制和缓存一致性保证机制后的读写性能是否提升,本文设计了多种微基准测试来评估系统的性能.微基准测试包括申请内存对象、读操作、写操作和释放内存对象等基本操作.我们针对不同的应用访问模式,设计了9 种包含不同基本操作的微基准测试,并根据不同应用的访问程度设置了不同的对象大小和读写比例,如表3 所示.

Table 3 Operating Ratios of Nine MicroBenchmarks Test表3 9 种微基准测试的操作比例 %

3.2 分布式异构内存池性能测试

首先,我们对实现了缓存一致性保证机制的分布式异构内存池系统进行了详尽的性能测试.这些测试包括对比不同缓存一致性保证机制的测试、不同粒度对象的测试、不同读写比例负载的测试以及应用测试.

1)不同缓存一致性保证机制的性能测试.我们在分布式异构内存池中实现了客户端缓存机制和可动态转换的缓存一致性保证机制.引入缓存机制后,系统的性能理论上会有显著提升.我们通过对系统性能进行测试来验证这一点.首先,测试了基于目录和基于广播的单一缓存一致性保证机制在系统性能上的差异.接下来,进行了动态转换的缓存一致性保证机制与现有单一机制的性能对比实验.在表3 中,对9 种不同读写比例的微基准测试集进行了测试.分别测试了存储对象大小分别为128 KB,256 KB 和512 KB 的粒度.关于对象的访问模型,采用了均匀分布和Zipfian 分布2 种访问模型进行测试,每组测试都进行了3 次重复实验,并取平均值来计算延迟性能的提升百分比.

为了测试不同缓存一致性保证机制对系统性能的影响,我们分别测试了系统在使用基于目录的缓存一致性保证机制和基于广播的缓存一致性保证机制时的性能提升效率,本文中分别用DIC 和SNOOP代表2 种机制.图3 展示了在均匀访问模式下,系统使用单一缓存一致性保证机制时的性能提升情况,其中包括3 种大小不同的对象.图3 中纵坐标表示使用一致性协议的系统相对于不使用一致性协议系统的性能提升比例.所有工作负载都取得了正向性能提升,平均性能提升比例达到了2.087.其中,对于读操作多于写操作的负载A,D和E,性能提升比例最大.由于系统在读取时可以直接从缓存中读取,而不必去远程读取,因此这些读多写少的负载可以获得较大的性能提升.然而,在写操作时,系统不仅需要写入远程节点,还需要发送请求来刷新缓存.

Fig.3 System performance for workloads under uniform accesses using a single cache consistency mechanism图3 均匀访问模式下使用单一缓存一致性保证机制的负载的系统性能

因此,对于写操作较多的负载如负载B和负载G,由于写操作较多,读缓存带来的性能提升被过多的写操作削弱,系统性能提升较小.这些写操作较多的负载在2 种机制下的性能提升比例相差不大,这是因为这2 种机制下都需要进行远程写入并返回,并由客户端发起缓存刷新请求,因此客户端的负载运行时间差别不大.此外,对于读操作多于写操作的负载如负载A,D和F,使用基于广播的缓存一致性保证机制带来的性能提升大于使用基于目录的缓存一致性保证机制带来的提升,这与本文设计部分中所述的机制设置特点是一致的,即广播机制更适用于读操作多于写操作的负载,而目录机制更适用于写操作多于读操作的负载.

图4 展示了在Zipfian 访问模式下,系统使用基于目录的缓存一致性保证机制和基于广播的缓存一致性保证机制时的性能提升情况.在Zipfian 访问模式下,访问更加集中于某几个热点数据,因此相比于均匀访问模式,大多数负载的性能提升比例更大,平均性能提升比例达到了2.395.在均匀访问模式下,大多数工作负载会进行一半的远程读取和一半的本地缓存读取,而在Zipfian 访问模式下,这些负载会进行更多的本地缓存读取,而其需要更新的缓存数据较少,因此性能提升较为显著.此外,由于系统的客户端缓存采用了简单的LRU 缓存而不是热点缓存,因此在Zipfian 访问模式下,个别负载如负载B和G的性能提升效果并不理想.这2 个负载都涉及较多的写操作,它们对于热数据并不敏感;无论是否缓存,对于写操作都需要进行远程写入,导致它们的系统性能提升相对较小,相比均匀访问模式没有显著差异.

Fig.4 System performance of workloads under Zipfian accesses using a single cache consistency mechanism图4 Zipfian 访问模式下使用单一缓存一致性保证机制的负载的系统性能

为了测试混合缓存一致性保证机制与不可转换的单一缓存一致性保证机制的性能差异,我们在可动态转换的缓存一致性保证机制下进行了相关测试,并将其与使用基于目录的缓存一致性保证机制的系统以及使用基于广播的缓存一致性保证机制的系统进行了性能对比,计算了性能提升率.系统中动态切换时机会影响系统性能.若转换周期较短,会对系统增加更多的判断和转换的开销,会降低动态转换带来的性能优势;若转换周期较长,则会降低用于转换决策的统计数据的时效性,降低转换策略本身性能提升幅度.因此,通过对数据集的先验测试,本文将默认的调整周期设置为1 000 次共享数据的访存操作.系统每隔1 000 次操作进行1 次缓存一致性保证机制的转换判定.我们用“MIXED”代表可动态转换的缓存一致性保证策略下的实验结果.

与基于目录机制的系统对比的实验结果如图5所示,可动态转换的缓存一致性保证机制在所有负载下都取得了更好的性能提升.所有实验结果的读写性能平均提升了32.3%.在基于目录机制的缓存一致性保证机制下,系统每次读取操作都需要进行远程查询脏位置或远程读取,而在进行机制转换后,系统可以在读取较多的负载中采用基于广播的缓存一致性保证机制,从而避免了大量的远程脏目录查询,直接进行本地缓存读取并返回结果,因此对于读取较多、写入较少的负载,如负载A和负载D,系统的性能提升比例较大.此外,由于我们采用的微基准测试负载都是连续地读取和连续地写入操作,因此系统进行缓存一致性保证机制转换的次数相对较少,仅在调用接口后进行了几次机制的转换.因此,对于均匀读写的负载,其性能提升程度一般.可以预测,在真实应用中,系统根据不同的运行时间段选择更合适的缓存一致性保证机制,将能够获得更优秀的系统性能.

Fig.5 System performance under dynamic conversion mechanism compared with the directory mechanism图5 相比于目录机制的动态转换机制下的系统性能

图6 展示了可动态转换的缓存一致性保证机制与基于广播的缓存一致性保证机制的系统性能对比结果.我们可以观察到,在所有负载类型下,可动态转换机制的系统都表现出比基于广播机制的系统更好的性能.具体而言,所有结果的读写性能平均提升了31.2%.在基于广播的缓存一致性保证机制下,写操作需要刷新所有客户端的缓存,因此对于写操作较多的负载,如负载B和负载G,采用可动态转换的缓存一致性保证机制的系统获得了更好的性能.此外,对于读写均匀的负载,由于这些负载是连续的读写操作,因此系统进行缓存一致性保证机制转换的次数较少,导致性能提升较小.

综上所述,相较于未实现客户端缓存机制和缓存一致性保证机制的系统,动态转换的缓存一致性机制可大幅度提升缓存的性能,尤其对于读操作较多的负载,系统性能提升更为显著.与基于目录的和基于广播的缓存一致性机制相比,本文实现的可动态转换的混合缓存一致性保证机制进一步提升了系统性能.

2)对象粒度对性能的影响.为了进一步研究对象粒度对性能的影响,我们进行了基于目录、基于广播和可动态转换的缓存一致性保证机制下不同对象粒度的实验.本文设置了从8 KB 到1 MB 共8 个梯度的对象,并对负载A,B和C进行性能测试.实验结果如图7 所示,最上面的3 条结果是负载A的性能提升比例,中间3 条结果是负载C的性能提升比例,最下面的3 条结果是负载B的性能提升比例.负载A是读操作较多、写操作较少的负载,负载B是读操作较少、写操作较多的负载,负载C是读操作、写操作各占一半的负载.可以观察到,无论采用哪种策略,由于本地缓存读取速度更快,都带来了显著的性能提升.负载A具有最多的读操作,因此性能提升最为显著;负载B具有最多的写操作,因此性能提升较小;对于负载C,其读写操作均衡,因此性能提升介于A和B之间.

Fig.7 System performance at different object sizes图7 不同对象粒度下系统性能

对于不同的缓存一致性保证机制,基于广播的机制提升效果大于基于目录的机制,这是因为基于目录的缓存一致性保证机制在读取时需要进行远端脏目录查询,导致读操作较慢.然而,对于写操作,基于目录的缓存一致性保证机制无需更新大量客户端缓存,只需修改目录,从而减轻了服务器负载.此外,随着对象粒度逐渐增大,系统的性能提升逐渐减小.这是因为当系统对象变大后,本地缓存容量不足,导致本地客户端缓存失效,从而增加了远程读操作的次数,降低了系统的性能提升率.

3)负载的读写比例对性能的影响.根据以上结果我们初步得出结论,负载的读写比例对系统性能有较大的影响.为了具体研究负载的读写比例对系统性能的影响,我们在不同读写比例的负载下进行了均匀访问模式的系统测试.每个实验负载的读写操作总数为10 万次,根据读写比例的不同进行了分梯度的测试,涵盖了从全读到全写的情况.同时,对使用基于目录、基于广播和可动态转换的缓存一致性保证机制的系统进行了3 种对象大小的测试.

根据图8 可知,随着读写比例中读的比例下降、写的比例上升,系统的运行延迟逐渐增大.由于读操作可以利用本地客户端缓存,对于读操作较多的负载,其运行时间较短.然而,本文系统中的写操作仍需进行远程写,因此对于写操作较多的负载,其运行时间较长.此外,相较于使用基于目录的缓存一致性保证机制的系统,使用基于广播的缓存一致性保证机制的系统具有较小的运行延迟.这是由于基于广播的系统在读操作时减少了1 次远程目录查询操作,因此性能更佳.与单一的缓存一致性保证机制相比,可动态转换的缓存一致性保证机制取得了更好的性能.通过对比9 组结果,可以观察到对象大小越大,系统的运行延迟也越大.这不仅因为大对象的读写操作更耗时,还因为大对象可能更快地占用完缓存,从而触发缓存淘汰策略,进一步增加系统的运行延迟.

Fig.8 System performance under different read/write ratios图8 不同读写比例负载下系统性能

综上所述,负载的读写比例对系统性能有显著影响.基于广播的缓存一致性保证机制相较于基于目录的机制具有更低的运行延迟,而可动态转换的缓存一致性保证机制在各方面均表现更优.此外,对象大小的增加导致系统运行延迟增大,既因为大对象的读写操作更耗时,又因为大对象更容易触发缓存淘汰策略,进而增加系统的运行延迟.

4)真实应用的性能测试.以上测试均采用了微基准测试中的9 种负载.这些微基准测试中的读写操作都是连续进行的,并且访问模式较为单一.因此,本文针对PageRank 算法,采用wordassociation-2011数据集进行了真实应用的测试.该数据集包含10 617个节点和72 172 条边.实验测试PageRank 算法达到收敛所需的运行时间.由图9 可以观察到,实现了客户端缓存的系统性能远高于无缓存的系统.与未实现缓存的系统相比,基于目录的缓存一致性保证机制和基于广播的缓存一致性保证机制分别提升了PageRank 应用性能的1.7 倍和2.6 倍.而可动态转换的混合缓存一致性保证机制相较于单一的目录机制和广播机制,分别提升了72.9%和31.6%的性能.由此可见,所提出的混合缓存一致性保证机制在真实的应用场景也取得了显著的性能提升,具有很好的适用性.

Fig.9 Running time of PageRank图9 PageRank 应用的运行时间

3.3 分布式异构内存池扩展性测试

我们在实现缓存一致性保证机制的分布式异构内存池中进行了扩展性测试.实验分别运行了1~16个客户端,并测试了负载A、负载B和负载C在这些情况下的运行时间.实验中对象粒度大小设置为128 KB,对象访问模式为均匀访问,并采用了可动态转换的缓存一致性保证机制.

如图10 所示,随着分布式异构内存池系统中共享客户端数量的增加,系统性能逐渐下降,运行延迟不断增加.然而,系统的扩展性仍然较好.特别是对于负载A,随着共享客户端数量的增加,运行延迟的增加并不明显.这是因为负载A主要是读操作,每个客户端都可以读取自己本地的客户端缓存,各个客户端之间没有性能影响.对于负载B,该负载主要由写操作组成,随着客户端数量的增加,运行延迟明显上升.这是因为对于写操作,每次写操作都需要客户端向服务器发送缓存刷新请求,服务器会将最新的缓存数据发送给客户端,从而增加了服务器的负担.此外,由于实验资源的限制,一个实测机器在实验中运行了多个客户端程序,这也对性能产生了影响,进而导致延迟的增加.

Fig.10 System scalability test图10 系统的扩展性测试

综上所述,在实现了客户端缓存机制和多客户端共享机制后,系统的多客户端扩展性较好.然而,对于写操作较多的负载,扩展性仍有改善的空间.

4 总结

本文提出了一种可动态转换的分布式异构内存池中的缓存一致性保证机制以提高效率.在该机制中,通过多客户端共享机制实现多客户端对远端存储对象的读写操作.采用基于目录和基于广播相结合的混合缓存一致性保证机制,并根据缓存数据块的访问模式动态转换使用不同的机制.通过矩阵分析判定每个数据块的访问模式,并选择适合的缓存一致性保证策略:对于读多写少的数据块,选择基于广播的机制;对于写多读少的数据块,选择基于目录的机制.这种方式提高了数据同步效率,进一步提升了使用缓存的性能优势.实验结果表明,相较于使用单一基于目录或基于广播的缓存一致性保证机制的分布式异构内存池系统,采用可动态转换的机制分别提升了32.31%和31.20%的系统平均读写性能.此外,在多客户端环境下,可动态转换的缓存一致性保证机制展现出良好的扩展性能.

作者贡献声明:段卓辉和刘海坤提出了设计思路和实现方案;赵金玮和刘一航负责实现并撰写论文;廖小飞和金海提出指导意见并修改论文.

猜你喜欢

内存一致性客户端
关注减污降碳协同的一致性和整体性
注重教、学、评一致性 提高一轮复习效率
IOl-master 700和Pentacam测量Kappa角一致性分析
外部高速缓存与非易失内存结合的混合内存体系结构特性评测
“春夏秋冬”的内存
县级台在突发事件报道中如何应用手机客户端
孵化垂直频道:新闻客户端新策略
基于Vanconnect的智能家居瘦客户端的设计与实现
基于事件触发的多智能体输入饱和一致性控制
基于内存的地理信息访问技术