我们与英特尔合作,对英特尔® Optane™ DC 持久内存模块(以下简称 PMEM)和经过最小修改的 memcached 进行了实验,以回答这些问题。这篇文章回顾了基准测试结果以及未来缓存系统代码架构的可能性。
英特尔® Optane™ DC 持久内存模块是与 DDR4 兼容的内存模块,可以在断电后记住内存,无需电池辅助。但是,它需要兼容的主板和处理器才能运行。
DDR RAM 有速度、功能和密度的不同版本。对于服务器来说,功能和速度往往由系统中其他组件的搭配决定:主板、CPU 速度等等。主要的选择是您希望 RAM 的密度有多高。
典型的服务器 DRAM 模块(截至今天)的大小在 8 到 64 吉字节之间。每种密度都有自己的价格范围。
DRAM
16G $7.5/gigabyte
32G $7/gigabyte
64G $9/gigabyte
128G $35/gigabyte
128G 模块是新的且罕见的,其成本极高。系统构建者必须权衡利弊:内存插槽与 DRAM 密度。云提供商通常希望系统密度高、体积小、价格低廉。
英特尔推出的这些新模块的密度为 128G、256G 和 512G。每吉字节的成本在 128G 时最低,在 512G 时最高。系统性能随着系统中模块数量的增加而提高。
对于缓存系统来说,128G 模块似乎最适合。本文的其余部分探讨了配置了 128G 模块的系统的性能。
在进行最少或根本没有更改的情况下,我们看到了哪些性能特征?我们能从中学到哪些关于如何设计未来的知识?我们采用了三种主要配置
Extstore 是 memcached 的扩展,它利用标准 SSD/NVME 设备来卸载内存。它通过将元数据和键数据保存在 RAM 中,并将项目的“值”部分指向存储来实现这一点。这种权衡对于具有相对较大的值(1k-8k+)的项目非常有效。在较小的尺寸(低于 1k)下,您需要相对于可以使用磁盘空间而言大量的 RAM。
虽然 extstore 对于较大的值非常有效,但 memcached 缺乏处理大量较小项目的方案。PMEM 也可以与 Extstore 结合使用:项目元数据和键在 PMEM 中,值在 NVME 闪存存储中。
测试使用 memcached 1.5.12 和 mc-crusher 进行,测试脚本 在此处提供
测试在一台运行 Fedora 27 和 4.15.6 内核版本的单台机器上运行。机器硬件规格如下
测试机器是 NUMA 多插槽服务器。一个 NUMA 节点用于运行 memcached 服务器。另一个用于运行 mc-crusher 基准测试。还为延迟采样过程保留了一个 CPU 核心。
进行了以下操作系统级别的配置更改
/usr/bin/echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
echo "4096" > /proc/sys/net/core/somaxconn
cpupower set -b 0
cpupower frequency-set -g performance
延迟采样应用程序使用 TCP 协议通过本地主机进行通信,因为它本身没有出现与主基准测试相同的回归。这样做是为了通过添加 TCP 协议栈来获得更接近实际情况的延迟结果。
所有测试中,项目值的尺寸均为 256 字节。加上键和元数据,平均每个项目略高于 300 字节。
测试中加载到服务器的键数量为 1.25 亿或 10 亿。这提供了性能基线,然后展示了扩展到超出 DRAM 限制时的额外开销。在这两种情况下,哈希表都具有 93% 的负载因子,这将在下面讨论。
使用了三个小的补丁来协助基准测试。
补丁允许同时监听 UNIX 域套接字和 TCP 套接字。这通常是不允许的,因为用户很容易错误配置客户端或意外地将一个锁定在本地主机的实例留在互联网上。有了这个补丁,我们可以在通过 UNIX 套接字生成负载的同时,通过 TCP 协议栈采样延迟。
补丁添加了一个命令来强制哈希表扩展。通常情况下,Memcached 在哈希表使用率达到项目与桶的比率的 1.5 倍时会自动扩展其哈希表。在一些实验中,我们测试了哈希表的超尺寸。详细信息如下。
补丁在使用特定客户端标志创建项目时,使用 malloc 分配内存。这在基准测试中没有使用,但在实验中使用。
在所有情况下,Memcached 都配置为使用 48 个工作线程。所有测试都使用相同的启动参数,只是使用的内存量和来源不同。唯一的其他变化是禁用 LRU 爬虫。这是一个低优先级的后台线程,我们确保它不会随机干扰测试结果。
与 Memcached 的连接是粘性的,绑定到特定的工作线程。以下所有测试都为每个基准测试线程创建了足够的连接,以利用 Memcached 的所有工作线程。
此快速入门指南 与我们为每个测试配置硬件的方式类似。
Optane 内存的不同模式在此处描述 - 我们使用内存模式和应用程序直接模式。
在此模式下,DRAM 用于 memcached 的内部结构和缓冲区,以及其链式哈希表的数组。
所有项目数据:元数据、键和值都直接存储在持久内存区域中。
持久内存使用 DAX 文件系统 和 memcached 的 可重启模式 原型补丁启用。持久内存通过 mmap 的文件访问。
注意:可重启模式 已在 1.5.18 中发布。只需添加 -e /path/to/dax/mount/memory_file
即可让 memcached 使用应用程序直接模式。
注意:可以 使用大页 来提高 DAX 文件系统的性能。我们没有测试这一点,但在某些情况下它可能会提供显著的性能提升。
随机选择器
均匀 - 随机选择键,每个键被获取的概率相同。
zipf - 在幂曲线选择键,编号较低的键被获取的频率更高。
键计数
10 亿 - 300G+ 的存储空间。注意:DRAM 基线始终为 1.25 亿个键。
1.25 亿 - 工作集适合所有硬件配置的 RAM。
吞吐量测试:每个基准 48 个连接。核心。最大请求速率。
大量批处理请求和响应。低系统调用率。
大量批处理请求,非批处理响应。中等系统调用率。
延迟测试:每个连接每 75 毫秒 50 个请求。每个基准核心 400 个连接。高系统调用率。
只读
99% 读取,1% 写入
90% 读取,10% 写入
延迟百分位数 - 仅影响延迟测试图表
调整这些测试是一个真正的挑战。在我们大多数实验中,所有三种模式都几乎相同。这里可见的差异是一个创造性的练习。
DRAM 作为我们的基线,但由于我们没有 400 GB 的 RAM,因此没有简单的方法将 DRAM 与 PMEM 直接比较,以进行大型工作负载。这种比较仍然有效:我们展示的是将许多机器与适合 DRAM 的工作负载进行比较,而不是将一台机器与比 DRAM 工作负载大得多的工作负载进行比较。以下是一些快速解释,以帮助理解测试结果
App Direct 模式是一个真正的惊喜:与内存模式不同,它根本没有缓存任何内存,性能既好又坏。
Zipf 分布提高了内存模式和 App Direct,吞吐量和延迟都有显着提高。内存模式更紧密地跟踪 DRAM 吞吐量。
在步调测试下,平均延迟几乎相同。Memcached 在处理请求时很少接触项目内存,因此虽然 App Direct 的延迟更高,但差异会被正在进行的其他所有事情淹没。
我们花了很长时间验证、重新运行和重新优化这些测试。如果您习惯于测试普通的 SSD,甚至 NVME 驱动器,那么这些结果是不真实的。接下来让我们讨论这与生产部署有何关系。
Memcached 用户有两个瓶颈需要规划:网络和内存容量。最近,extstore 用户必须应对在大量写入下闪存驱动器烧毁的工作负载。
吞吐量几乎是无限的。在所有情况下,实际的网卡都会在服务之前失效。1000 万个 300 字节的响应超过了 20 吉比特的流量。在几乎所有已知的 memcached 工作负载中,项目的尺寸差异很大,从几个字节到 500 千字节或更多。如果系统存储了各种尺寸的项目,它可以轻松地使 50 吉比特网卡饱和。
让我们以 300b、1kb 和 2kb 的 TCP 响应(键/值 + TCP/帧头)为例。现在,假设我们测试的机器的重负载下,读取负载的峰值为每秒 800 万个请求,那么 NIC 饱和是什么样的呢?
在 2 千字节的平均值下,用单个实例使 100 吉比特 NIC 饱和成为可能。现实总是会降低这些数字:系统调用开销、中断轮询速率等等。Memcached 目前在写入方面也没有那么好的扩展性。对于高写入速率的工作负载,我们将不得不付出努力才能达到 100 吉比特。
人们经常在专用硬件之上使用 DPDK 或类似的自定义用户空间网络堆栈。Memcached 倾向于保持部署尽可能简单,并且不支持这些库。此外,很少有用户在单个节点上每秒突破 10 万个请求,因此通常不需要这些库。
从我们看到的情况来看,PMEM 等同于 DRAM,适用于典型的网卡。
内存密度是决定一家公司需要多少个 memcached 服务器的另一个主要因素。你需要足够的 RAM 来获得高命中率,以显著降低后端负载,或者将工作集放入内存。
你可以拥有的 memcached 实例数量有限。在故障期间,其他服务器必须承担剩余的工作:数据库后端承担额外的未命中,以及剩余 memcached 节点的网卡。
拥有一个新的密度级别为扩展数据缓存的大小提供了更多机会。缓存来自国外数据中心、AI/ML 模型、预先计算或预先模板化的渲染的数据。
我们有一个良好的开端。即使不修改现有代码,该服务在任何现实场景中都与 DRAM 的性能几乎相同。如果我们想改善这种情况,用户首先需要对微秒级的延迟非常敏感。要优化的另一个目标是通过减少对 PMEM 的写入来延长设备寿命。英特尔保证全负载写入 3 年,但这可能很重要,如果一家公司打算在高负载下持续使用硬件 5 年以上。尽管如此,如果由于担心驱动器过早烧毁而无法使用闪存设备,PMEM 也是一个不错的选择。
关于这一点,如果你符合这些条件中的任何一个,我们非常希望收到你的来信!我们不知道有任何用户会受到此限制。
1.5.18 版本发布的功能 允许 memcached 在干净关闭的情况下重启。对于许多工作负载来说,这是一个糟糕的主意。
但是,如果您的应用程序能够排队和重试缓存更新或失效,或者它对您的工作负载来说并不重要,那么可重启性将是一个巨大的优势。Memcached 池的大小为 N+1(ish)。您需要足够的服务器来容忍一台服务器宕机时的额外丢失率。如果一台服务器升级,您必须等待替换服务器填充一段时间才能继续。
在可重启模式下,项目内存和一些元数据存储在共享内存段中。当 memcached 重启时,如果它仍然与旧数据兼容,它将重建其哈希表并提供其先前的数据。这使得升级更容易进行。无论您是在 DRAM 上还是 PMEM 上,这都具有相同的功能。
即使这样,在重新启动机器时(例如内核更新)您仍然会丢失缓存。在 App Direct 模式下使用持久内存,您可以完全重启(甚至修复)机器而不会丢失缓存,因为该共享内存段将在重启后持续存在。只要在合理的时间内完成!
此更改不会使 memcached 崩溃安全。它是在与传统数据库不同的权衡下设计的。
最大化网络使用率、提高内存密度和减少集群规模可以将总拥有成本降低高达 80%。让我们来分解一下。
高端交换机(10g、25g、50g)每个网络端口的成本可能在数百到数千美元之间。减少缓存服务器的数量可以减少端口使用量和电力成本。由于 memcached 可以很好地利用更大的网络卡,分配的容量不会浪费。
Memcached 工作负载需要很少的 CPU。用户可能正在运行双插槽系统仅仅是为了将更多 RAM 放入单个系统中。仅从双插槽系统切换到单插槽系统就可以将每台服务器的成本降低近一半。
DRAM 价格始终有一个曲线,例如(对于当前的服务器 DIMM)
PMEM 的每 GB 成本(截至撰写本文时)大约是相同密度的 DRAM 的一半。
(注意:RAM 价格会波动,这些数字仅供说明。)
256G 32G 256G
DRAM DRAM Optane
+---+ +---+ +----+
|32G| |16G| |128G|
| | | | | |
|32G| |16G| |128G|
| | +---+ +----+
|32G|
| | $7.5/gig $4.5/gig
|32G|
| | $1392 total
|32G|
| |
|32G|
| |
|32G|
| |
|32G|
+---+
$7/gig -> $1792 total
以以上两个例子为例:要拥有 256G 的缓存,一种配置可能需要 8 个 RAM 插槽,每 GB 8 美元。RAM 费用为 2000 美元。获得 8 个插槽也可能需要多插槽服务器、更昂贵的主板或更高密度、价格更高的 RAM 插槽。与 PMEM 的组合仍然需要一些 RAM,但总的来说,您可以将单个缓存节点的成本降低数千美元。
以上示例展示了具有 256G DRAM 的节点。随着模块添加到机器中,性能几乎呈线性扩展。可以使用多 TB 节点来大幅减少缓存集群的大小,前提是网络允许。
大幅增加缓存大小可以降低其他方面的成本:互联网带宽或跨数据中心带宽、昂贵的数据库服务器、昂贵的计算节点等等。
如果您运行自己的数据中心,直接硬件购买很容易计算。PMEM 如何适应如今大多数人支付的云定价?
云定价对于这项新技术来说是一个很大的未知数。最近引入 NVME 设备时,云提供商将 4TB+ 驱动器放入具有最大存储量和 RAM 的大型实例中。这些实例非常昂贵,并且不适合 memcached 或带有 Extstore 的 memcached。
最近,出现了具有较小 NVME 量(约 750G 到 1TB)的节点,以及相应的减少的 CPU 和 RAM。我们希望看到云提供商为客户提供适合此市场的实例。
缓存和键值存储层是大多数基础设施的重要组成部分。拥有与云用户需求紧密耦合的实例对于初创公司来说可能是成败的关键,对于成熟公司来说是一个巨大的项目。如果用户不必过多地担心其架构中可能难以扩展或成本高昂的部分,他们就可以更快地推向市场。
英特尔®傲腾™ DC 持久内存模块具有高密度和极低的延迟。与数据库的需求相比,memcached 对 PMEM 的引用次数极少,因此性能几乎与 DRAM 相同:轻松超过每秒数百万次请求的 1 毫秒(甚至 0.5 毫秒)SLA。PMEM 还可以通过减少集群大小或增加可用缓存来大幅节省成本。此外,使用内存模式部署对于旧版本的 memcached 来说非常简单。
随着 NVME 和现在的 PMEM,我们看到了新型的超高密度缓存集群。
就像去年的 NVME 推出一样,我们认为这是数据中心存储的激动人心的时刻。这种行业很少出现革命,我们欢迎一切可以获得的东西。
我们在第二部分继续讨论,探讨我们在项目过程中思考和测试的软件和算法变化。