memcached - a distributed memory object caching system

超越 RAM 的缓存:NVMe 的案例 - Dormando (2018 年 6 月 12 日)

从堆栈的每一层到缓存架构都体现了性能和成本之间的隐含权衡。然而,这些权衡一直在不断变化:随着存储技术的进步、工作负载模式的变化或硬件供求的波动,新的拐点可能会出现。

在这篇文章中,我们探讨了 RAM 价格上涨对缓存系统设计的影响。虽然 RAM 一直都很昂贵,但 DRAM 价格在 2017 年上涨了 50% 以上,高密度 RAM 涉及多插槽 NUMA 机器,从而增加了功耗和总体成本。与此同时,闪存和傲腾等替代存储技术不断改进。它们具有专门的硬件接口、一致的性能、高密度和相对较低的成本。虽然将缓存从 RAM 卸载到 NVMe 或 NVM 设备上越来越具有经济效益,但对性能的影响尚未得到广泛理解。

我们将在 Memcached 的背景下探讨这些设计影响,Memcached 是一种分布式、简单、以缓存为中心的键值存储。有关快速概述,请参阅 关于页面故事教程

Memcached 具有一个 名为 extstore 的存储系统,它允许将部分数据保留在磁盘上以供“不太常使用”的键使用,从而释放 RAM。有关其工作原理的完整细分,请参阅链接,但简而言之:键保留在 RAM 中,而值可以拆分到磁盘。最近和频繁访问的键仍然会在 RAM 中保留其值。

此测试是在 Accelerate with Optane 的帮助下完成的,他们提供了硬件和指导。还要感谢 Netflix 采用 extstore,以及他们所有宝贵的反馈。

缓存 RAM 分解

db to cache breakdown

例如,一个 1TB 的数据库在给定时间段(比如 4 小时)内可能只有 20% 的数据是“活跃”的。如果你想缓存所有活跃数据,你可能需要 200G 的内存。在这 200G 的内存中,可能只有 20% 被高度利用。

cache hit rate breakdown

在使用的缓存内存中,只有 10% 的内存可能负责 90% 的缓存命中率。剩下的 90% 的内存只占 10% 的命中率。

然而,如果你减少 90% 的内存使用量,你的未命中率至少会翻倍,从而使数据库的负载翻倍。根据你的后端系统性能,丢失一些内存会使后端成本翻倍

cache size breakdown

分解内存中的项目,我们可能会发现绝大多数(在上述情况下为 97.2%)只存在于 30% 的内存中。一小部分较大的但仍然重要的项目占用了另外的 70%。即使更大的项目也可以很快消耗内存

请记住,这些较大的项目可能占网络利用率的很大一部分。一个 8k 的请求与 80 多个小的请求占用相同的带宽。

extstore breakdown

extstore 如何帮助?通过将较大的、最近使用较少的项目的 value 从 key 中分离并指向磁盘,我们可以节省大部分未使用的内存。根据用例,你可以

even distribution

其他工作负载变化可以吗?在上面的例子中,缓存命中率是均匀分布的。这个理论系统具有 400,000 的 IO 限制,这应该与高端 SSD 或 Optane 驱动器类似。在这种情况下,不能依赖内存来饱和网络。

在 400,000 IOPS 下,只需要 3072 字节的平均值就可以饱和 10G 网卡。8192 字节用于 25G。在设计良好的集群中,需要额外的空间来应对增长、使用峰值或池中的故障。这意味着平均值可以低至 1024 字节,但是,在 1024b(假设每个 key 有 100 字节的开销)下,extstore 只能将磁盘上的存储量提高到内存的 10 倍。

需要仔细的容量规划 并非所有人的工作负载都与外部存储兼容。在使用磁盘作为缓存之前,请仔细评估 RAM 在缓存池中的使用方式。如果您只有小型项目、较短的 TTL 或高写入速率,RAM 仍然会更便宜。可以通过监控 SSD 的“每天写入次数”来计算这一点。如果一个 1TB 设备可以在 24 小时内写入 2TB 数据的情况下存活 5 年,那么它的容忍度为 2 DWPD。傲腾的容忍度很高,为 30DWPD,而高端闪存盘的容忍度为 3-6DWPD。

测试设置

测试是在一台英特尔至强机器上进行的,该机器拥有 32 个核心、192GB 内存、一个 4TB SSD 和 3 个 750GB 的傲腾驱动器。测试期间只使用了一个傲腾驱动器。截至撰写本文时,extstore 只能与一个驱动器一起使用,这种配置反映了大多数用户的配置。

在每次测试运行期间,mc-crusher 客户端的数量以及服务器中 extstore IO 线程的数量都会发生变化。IO 线程太少会导致设备无法饱和,而 IO 线程太多会导致设备过载并可能造成队列。

每次测试在预热后运行一分钟。

延迟和吞吐量测量

由于 mc-crusher 不计时结果,因此使用两个脚本生成结果数据

对于每个测试,都提供了延迟样本的完整细分。采样以每毫秒一次的最大速率进行。
注意:没有使用事件循环,以避免必须确定时间流逝,因为如果一堆事件同时发生,则需要确定等待处理的时间。

测试

进行了三个一般测试

结果

不幸的是,图表中有一些波动;这是由于在测试期间留下了过少的可用 RAM。optane 的性能是一致的,而操作系统难以跟上。

作为参考:针对此确切配置的 memcached(32 个线程等)的纯 RAM 多获取负载测试会导致 **每秒 1800 万个键**。更人为的基准测试使具有多个内核的服务器达到了 **每秒 5000 万个键**。

**使用少量 extstore I/O 线程**,Optane 驱动器能够更接近于饱和 I/O 限制:4 个线程,4 个客户端:230k Optane,40k SSD。延迟细分显示 SSD 通常在等待时间上高出一个数量级,Optane 保持在 10us 桶中,而 SSD 在 100us 中,滑入 1ms。

**使用大量 extstore I/O 线程**,底层操作系统变得饱和,导致 Optane 图表中的波动和排队。同时,SSD 继续从额外的线程资源中获益,这些资源是克服闪存带来的额外延迟所必需的。

对于许多工作负载,SSD 和 Optane 都完全可行。如果大部分读取仍然来自 RAM,而 extstore 用于服务仅大型对象的尾部,它们都能将响应时间保持在 1ms 以内。

**如果你想突破 extstore 的界限**,像 Optane 这样的驱动器将大有帮助

测试类型 SSD IO 线程 傲腾 IO 线程



学习

结论

由于成本原因目前无法实现的工作负载现在可以实现了。大多数包含混合数据大小和大型池的工作负载可以显著降低成本。


extstore 每个磁盘上的项目都需要 RAM。此图表假设每个项目 100 字节的开销(键 + 元数据),可视化了随着项目大小的增加,RAM 开销如何下降。

DRAM 成本是傲腾的 3-4 倍,是 SSD 的 4-8 倍,具体取决于驱动器。

随着缓存从 RAM 转移到傲腾(或闪存),纯粹用于 RAM 的支出可以降至 1/3。

减少 RAM 减少了对多插槽服务器的依赖以获得非常高的 RAM 密度,NUMA 兼容机器通常是必要的。这些机器有多个插槽、多个 CPU,一半的 RAM 连接到每个 CPU。由于 memcached 效率很高,因此您可以同时减少 RAM,以及减少一半的主板/CPU 甚至电源成本,一旦 RAM 减少。对于特定工作负载,高达 80% 的成本降低是合理的。

高速、低延迟 SSD 开启了数据库和缓存设计的新时代。我们展示了各种用例的高性能数据,既可以降低成本,也可以扩展缓存的使用。