关于Fast key-value stores: An idea whose time has come and gone的梳理

文章探讨了远程内存键值存储的局限性,提出链式内存键值存储(LINK)作为替代方案,强调有状态应用进程服务器的性能优势,并讨论了自动分片和数据一致性等问题。作者认为,通过集成到应用进程服务器,LINK可以减少编组成本和超读,提高数据中心服务的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要

像Memcached、Redis这样的远程内存键值存储被广泛的应用于工业领域,而且是学术研究的活跃领域。作者认为这种远程内存键值存储的时代来了又走了:这种存储所采用的域无关API将复杂性推给了应用,进而导致额外的编组开销和网络跃点。相反,数据中心服务应该采用有状态应用进程服务器,或者带有特定于域的API的自定义内存存储来构建,从而,与远程内存键值存储相比能够以更低的消耗提供更高的性能。此前由于缺少合适的基础架构支持,这种设计思想实施起来极具挑战性,现如今随着自动分片技术的到来,作者认为是时候了!

主要内容

  • 评估有状态设计的潜在性能改进
  • 提出一种新的概念——链式内存键值存储

关于远程内存键值存储(RINK)

使用这种存储可以实现两个目的:
首先,它们可以通过存储系统提供缓存,以便更快地检索持久状态。
其次,它们可能会存储短期数据,例如每个会话的状态,这些数据不保证持久性。

由于 RInK 存储处理定义明确且简单的操作,因此实施能够实现极高的吞吐量和低延迟,此外,这些存储的高性能使得分布式缓存挑战(如负载平衡)相对不那么重要。
前面有提到远程内存键值存储采用了域无关API将复杂性抛给了应用,例如,它们强制应用进程在本机语言表示形式和字符串之间重复转换其内部数据结构,这带来了 CPU 成本和进程负担。当应用进程不使用每个从 RInK 存储中检索的值,这个问题会进一步加剧,因为字节被不必要地传输,只能被丢弃。最后,网络距离会带来延迟成本,特别是当必须传输大值或需要多次往返时。

作者在2.1中陈述了一系列S+RInK结构的好处,也在2.2中指明了该结构的缺陷:将 RInK 存储的域无关 API 确定为阻碍端到端应用进程性能的缺陷。

本文的三点贡献

  • 作者认为,将应用进程代码和缓存的内存状态耦合(指的应该是有状态应用进程服务器)会带来被低估的性能优势
  • 本文提出了一种新的链式内存键值存储抽象
  • 通过消灭远程内存存储来获取内存状态的同时,聚焦于提升应用进程性能

关于链式内存键值存储(LINK)

LInK 存储是链接到应用进程服务器或自定义内存中存储的键到丰富对象的映射,用于替换外部 RInK 存储

无状态远程内存存储的局限性

  • 由编组和解组产生的CPU成本
    由于编组和解组涉及数据格式的转换和处理,会引入额外的CPU成本。编组阶段需要将数据转换为目标格式,这可能涉及序列化、压缩等操作。解组阶段则需要将接收到的数据解析并恢复为原始格式。这些编组和解组操作可能会占用相当数量的CPU时间,特别是在大规模数据集或高频率数据交换的情况下。因此,对于需要频繁进行数据编组和解组的应用程序或系统,这些CPU成本可能会对性能产生影响。
  • 超读
    🎨(补充)超读在远程内存键值存储中可能出现的原因有以下几点:
    1、网络延迟:远程内存存储需要通过网络进行数据的读取和写入。网络延迟可能导致读取操作的响应时间较长,从而增加了超读的风险。如果读取的数据量过多,或者不精确地指定所需的数据范围,就会浪费带宽和时间。
    2、缓存未命中:远程内存存储通常会使用缓存机制来提高读取性能。但是,如果所需的数据在缓存中不存在,就会发生缓存未命中。这会导致存储系统从远程节点读取额外的数据,以满足当前读取请求,并可能产生超读现象。
    3、键值模型:远程内存键值存储使用简单的键值对模型来保存数据。如果没有准确的指定所需的键或范围,例如获取某个特定键的值时,可能会无意中读取到其他键的数据,从而导致超读。
  • 网络延迟

远程内存键值存储研究现状

虽然接下来介绍的是最先进的远程内存存储,但前面所提到的几个局限性依然存在。

基本远程内存键值存储研究现状

基本的 RInK 存储实际上提供了一个只有 PUT/GET API 的接口。

FaRM 尝试通过使用 RDMA 降低获取远程数据的成本来提高无状态应用进程的性能;NetCache 解决了内存中存储的负载倾斜问题,直接在网络交换机中为热键提供了额外的缓存层;KV-Direct 利用可编程 NIC 绕过远程 CPU,实现对远程内存的高吞吐量访问,同时提供比传统 RDMA 更丰富的语义。

作者认为上述改进注重于提升PUT/GET操作的性能,而非解决(非)编组成本和超读问题

扩展的远程内存键值存储研究现状

相比较基本的RInK存储,扩展的RInK存储提供更加丰富的域无关API。

Gribble等人建议构建一小组集群规模的分布式数据结构;Splinter 允许应用进程将小段代码发送到存储区;

作者认为这些扩展符合所提倡的自定义内存存储的精神。作者主张进一步采用这种方法,尽可能将存储嵌入到应用进程服务器中,并提供一组更丰富的功能,例如动态负载平衡和复制。

消灭远程内存键值存储

作者认为,在实施可扩展的数据中心服务时,不应使用RInK存储。在本节中,作者将介绍如何通过为有状态服务提供两种标准架构来消除现有架构中的 RInK 存储。

有状态应用进程服务器

这种架构有效地融合了RInK和应用进程服务器,当 RInK 仅由单个应用进程访问并且所有请求都访问单个密钥时,这是可行的。

这种架构消除了上面提到的无状态远程内存存储的局限性,因为缓存存储着应用进程对象,这样是不存在(非)编组、超读和网络延迟问题的。
🔍如何通过实验得到上述结论????

自定义内存存储

自定义内存存储是带有一个特定域接口的分离的、内存缓存,此体系结构会产生相对于有状态应用进程服务器的额外网络跃点,这意味着它只会缓解而不是消除 RInK 存储的问题。例如,它仍然可以使用特定于域的 API 减少解组开销和过度读取;另一方面,为了交换网络跃点,它允许在多个应用进程和语言之间共享单个缓存。

作者简单从下述几点说明,自定义内存存储可以取代RInK,并且可以提供相同甚至更好的性能:
**扇出:**在处理单个逻辑操作时,无状态应用进程服务器需要从RInK中读取很多的键,而自定义内存存储中的特定域API可以减少超读。
🎨(补充)“fanout” 是一个广泛应用于计算机系统和网络中的术语,通常用来描述信号、数据或消息从一个源点传输到多个目标点的过程。它表示数据从一个节点扩散到多个子节点或接收者的数量。

**共享:**RInK 存储通常用于提供由多个不同应用进程共享的缓存,以实现跨应用进程集成(例如在电子邮件客户端中显示日历)或避免在单独的缓存中重复数据。自定义内存存储不仅可以实现该功能还可能有更高的执行效率。

**资源分解:**服务所有者可能更喜欢将工作负载的 CPU 和内存密集型部分隔离在不同的进程(即应用进程服务器和 RInK)中,以便可以单独配置它们。在某种程度上,RInK 存储支持更高效的预配,而自定义内存中存储也可以。

链式内存键值存储

在介绍链式内存存储之前先对自动分片做简单介绍。

自动分片

自动分片与有状态应用进程服务器之间的牵绊

自动分片系统是有状态应用进程服务器的必要构建块:如果没有对服务器故障和工作负载变化(例如热键)做出反应的能力,大规模部署有状态应用进程服务器是不切实际的。

自动分片的欠缺之处

作者认为若简单地将应用进程的键分配给服务器的自动分片系统会留下一些重要的问题。

  • 自动分区与分区键有关,但应用进程必须要处理值。把键从一台服务器部署迁移到另外一个服务器时,自动分片不会对相应的值进行迁移。新部署的服务器就需要对其值进行恢复,特别是如果值不存在于持久存储中,就会发生丢失,影响使用体验。
  • 需要获取(部署在多个服务器上的)键值的副本并且实现其所对应的值的一致性的应用进程要自己创建函数来实现该功能。
  • 应用进程可能需要相对于某些基础数据存储保持缓存状态最新。

🎨(补充)“Auto-Sharder” 是一种自动分片工具或模块,用于帮助管理和执行数据库或数据存储系统的自动分片过程。它通常是一个软件组件或功能,旨在简化和自动化数据的水平划分和分布,以提高系统的可扩展性和性能。

LInK 存储

LInK 存储是对自动分片的高级抽象,它提供分布式内存中的键值映射,其中丰富的应用进程对象作为值,而不是字符串或简单的数据结构。作为高级抽象,它提供了比自动分片更丰富的功能。LInK还具有以下特征:

  • 数据一致性
  • 高可用性
  • 支持再分片
  • 状态丢失通知
  • 刷新
    LInK 存储的架构依赖于自动分片,使用链接到客户端的路由器库将请求从应用进程客户端定向到应用进程服务器。应用进程服务器链接一个名为 Linklet 的新库,这是 LInK 存储实现;它封装了与自动分片的所有服务器端交互。当自动分片重新分片时,在不同应用进程服务器上运行的 Linklet 实例通过 RPC 交换应用进程状态。

🎨(补充)“Route library”(路由库)是指用于处理和管理路由逻辑的软件库或模块集合。它提供了一组API和工具,帮助开发人员构建和维护路由功能,以实现数据包、消息或请求的转发和传输。路由库在网络通信、分布式系统和云计算等领域中扮演着重要角色。它们为开发人员提供了抽象接口和工具,使得构建和管理复杂的路由逻辑变得更加简单和可靠。不同的编程语言和框架可能会提供不同的路由库,开发人员可以根据自己的需求选择适合的库进行使用。
在这里插入图片描述
Linklet将一个新的API暴露在外,此 API 的一个重要方面是存储的值是本机应用进程对象(模板参数 V)。要使 Linklet 能够传输值以响应重新分片事件,应用进程必须提供代码以(取消)编组其对象。开发人员在使用 RInK 存储时必须编写(取消)编组代码,因此此 API 不会增加额外的负担。与 RInK 存储不同,编组器并非在每个请求的关键路径上。

开放性问题和机遇

开放性问题

  • 负载平衡算法有状态体系结构需要跨各种应用进程和工作负载运行的负载平衡算法。目前也有这种算法,但存在着一些开放性问题:同时平衡多个指标,对重新分片应用进程的成本进行建模,并快速识别负载的突然变化并做出反应,而不会引起振荡。
  • 复制复制是实现高可用性的重要技术。在 RInK 存储中,复制可以应用于存储的数据并与应用进程逻辑隔离。在LInK存储中应用进程代码和数据的紧密耦合使问题更加复杂。
  • 最小化应用进程占用空间上面提出的 LInK 实现依赖于大量链接功能融入应用进程本身,这有两个缺点。首先,它使支持多种语言变得更加困难;其次,它使修复 LInK 实现错误变得更加困难,因为开发人员必须发布新的二进制文档。确定有多少 LInK 架构可以提取到单独的 RPC 距离控制服务中是一个悬而未决的问题。

机遇

  • 更快的无服务器
  • 上下文和个性化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值