问题
内存缓存系统是云服务的基本构建块。例如Memcached[48]和Redis[58],在云服务[9,16,71,84]中被广泛采用,以减少服务延迟并提高吞吐量。由于云服务中请求的动态和突发特性[62,69,82],弹性,根据工作负载变化调整计算和内存资源的能力,是内存缓存系统的关键要求。
然而,由于单片服务器上的CPU和内存耦合,现有的缓存系统无法以资源高效和敏捷的方式弹性调整资源。实际场景中表现结果如图1。其存在两个问题:
-
资源效率低下。当分配耦合的CPU和内存时,应用程序对资源的需求必须四舍五入以适应这些固定大小的虚拟机(VM),导致整个数据中心的资源利用率低[8]。
-
资源调整缓慢。现有的内存缓存系统将数据分片到多个VM,以利用CPU和内存资源[22,28,43,58]。当新的虚拟机添加到缓存集群时,必须重新分片和迁移缓存数据。由于耗时的数据迁移,增加资源时的性能提升和缩减资源后的资源回收延迟了几分钟[39],会消耗额外的CPU周期和网络带宽,吞吐量下降,延迟增加[38,56]。
为了实现更好的弹性,可以将内存缓存系统移植到分解内存(DM)架构,在这种架构中,计算和内存资源是解耦的,可以灵活分配。计算池包含具有丰富CPU内核和少量DRAM作为运行时缓存的计算节点(CN)。内存池包含具有足够内存的内存节点(MN)和计算能力较弱的控制器(例如1-2个CPU核),以执行管理任务,即网络连接和内存管理。CN和MN通过具有高带宽和微秒级延迟的CPU旁路互连连接,例如RDMA和CXL[68],确保了内存访问的性能要求。DM架构具有以下优势:
-
解决了现有缓存系统的资源效率和弹性问题。DM可以以细粒度的方式根据应用程序需求单独分配计算和内存资源[76]。
-
数据迁移频率大大降低。DM上的缓存系统在扩展或减少内存时不需要迁移数据,因为计算池中的所有CN都可以访问内存池中的缓存数据。只有在某些特殊情况下,例如,由于工作负载偏斜,MN的网络带宽成为性能瓶颈,才需要数据迁移实现负载平衡。因此,在大多数情况下,可以消除迁移成本,使资源调整能够灵活地生效,而不会损失性能。
挑战
在DM上构建弹性缓存系统具有以下挑战:
-
通过绕过CPU的远程内存访问来访问缓存对象,会阻碍缓存算法的执行。缓存算法[11,58]需要监控缓存对象的热度,并维护热度信息来驱逐。现有的缓存算法依赖于执行所有数据访问的缓存服务器CPU,来监控对象热度并维护缓存数据结构[48]。然而,在DM上的缓存系统中,计算池中的应用程序(客户端)在访问对象时绕过内存池中的CPU,缺乏集中的热度监测器。导致缓存数据结构必须由客户端进行多次高延迟远程内存访问来维护。此外,在DM上为不同的工作负载支持各种缓存算法[11,58]更加困难,因为缓存算法会驱逐具有指定规则和定制数据结构的对象[33,73]。图2表示了维持缓存数据结构的开销,相比与KVS吞吐量显著下降。
-
资源调整会影响缓存算法的命中率。缓存算法的命中率与工作负载的数据访问模式[74]和缓存大小[59]有关。在DM中,这两个属性都会随着动态资源调整而变化。数据访问模式随着并发客户端(即计算资源)的数量而变化,缓存大小随着分配的内存空间(即内存资源)而变化。因此,最大化命中率的最佳缓存算法会随着资源设置而动态变化,固定缓存算法无法适应DM的动态特性。图3-图5显示了不同数据访问模式、不同缓存大小时缓存算法的效果,不存在单一的最优缓存算法。
本文方法
本文设计了DM上的缓存系统Ditto。
-
以客户端为中心的缓存框架,具有分布式热度监测和基于样本的驱逐功能,以解决在DM上执行缓存算法的挑战。分布式热度监测使用单侧RDMA动词在计算池中记录来自分布式客户端的访问信息,使用驱逐优先级正式描述对象热度,并通过对记录的访问信息应用优先级计算规则来评估对象的驱逐优先级。基于样本的驱逐方案通过采样多个对象并在客户端选择优先级最低的对象来选择驱逐受害者,而无需维护远程数据结构[58]。设计了一个样本友好的哈希表和一个频率计数器缓存,以提高DM框架的效率。
-
提出了分布式自适应缓存方案。来应对动态资源变化的挑战。由于缓存算法之间的关键区别在于它们对驱逐优先级的定义,因此可以通过定义量身定制的优先级计算规则来集成各种缓存算法,而只需很少的编码工作。Ditto使用以客户端为中心的缓存框架同时执行多个缓存算法,并使用遗憾最小化[26,27,85](一种在线机器学习算法)来感知性能,并在当前资源设置中选择最佳算法。
开源代码:https://github.com/dmemsys/Ditto
实验表明,Ditto能够有效地适应DM上不断变化的资源,在真实工作负载中比最先进的缓存系统高出3.6倍,在YCSB基准测试中高出9倍。
总结
针对分离式内存架构下的缓存系统,由于访问远程内存会绕过CPU,导致现有缓存策略无法正常运行,由于访问模式和资源动态变化,单一缓存策略无法提供最优效果。本文提出分离式内存下的缓存算法Ditto。(1)以客户端为中心的缓存框架,通过分布式热度监测访问信息,通过采样选择最低优先级进行驱逐。(2)支持多种缓存算法,使用遗憾最小化根据系统状态选择最优缓存算法。