数据库缓存层是否仍然必要?

了解为什么在数据库前放置缓存通常效果有限,以及一些关于缓存实际上是一件好事的情况的指南。

译自 Is a Database Caching Layer Still Necessary?,作者 Behrad Babaee。

正如我在 关于缓存的上一篇文章 中所讨论的,在数据库前面引入一个缓存层(无论是外部还是内部)在提高因数据访问缓慢而导致的应用程序性能方面效果有限。需要记住的关键点是,最终用户功能通常需要多次数据库访问。

为了让缓存改善最终用户体验,所有这些数据库查询都必须从缓存中提供。因此,除非缓存命中率异常高,否则缓存不太可能是有益的。

您可能想知道为什么大多数数据库技术都包含一个内部缓存层,或者为什么在数据库前面放置缓存技术是一种常见做法。简短的回答是,缓存有效地提高了吞吐量,但没有提高延迟。

吞吐量与延迟

理论上,吞吐量和延迟是独立的。这意味着有可能拥有一个吞吐量巨大但响应时间非常慢的系统。例如,我可以用请求的信息填充 1 PB 的磁盘,并在第二天晚上将它们运送给客户端。在这种情况下,系统的吞吐量将达到惊人的每秒 11.6 GB(1 PB/(24 小时 * 3600 秒))。然而,延迟将是令人沮丧的一天。

然而,在实践中,吞吐量不足会显着影响延迟。重新审视前面的示例,让我们考虑一下客户端现在请求 10 PB 的信息,但我们只有 1 PB 的磁盘可供装运。因此,交付过程将跨越多天:需要一天时间来运送第一个 PB,还需要一天时间让客户端退回磁盘。此循环将重复到第 19 天,届时所有数据最终将被运送。因此,吞吐量的缺乏将有效地将响应时间增加 19 倍。

使用缓存层增加吞吐量

基于前面的示例,引入缓存层类似于设置一个本地中心,该中心设计用于存储客户可能请求的 90% 的数据。该中心配备了每批次最多可发送 9 PB 数据的能力,从而可以在一小时内完成交付。

为了向客户交付 10 PB 的数据,可以在一小时内从本地中心运送 9 PB,剩余的 1 PB 将在第二天从主存储中交付。通过实施本地中心,我们已将吞吐量提高了十倍,并将响应时间提高了 19 倍。

至关重要的是要了解,响应时间的这种显着改善完全归功于吞吐量的增加;交付速度本身并不影响这种增强。

缓存还是不缓存

到目前为止,我们了解到添加缓存可以改善延迟,当且仅当迟缓是由于吞吐量不足时。在上面的示例中,如果客户对一天的响应时间不满意,则将装运磁盘容量或本地中心存储的数据百分比增加到低于 100% 的任何值都不会提高响应时间。

为了确定缓存是否可以有益,必须考虑数据库的算法和数据结构、它操作的硬件以及应用程序的数据访问模式。因此,没有一刀切的答案。我不想满足于含糊不清且令人不满意的“这取决于”的回答,而是希望在以下部分中提供详细的分析,概述缓存的优点和缺点。

不适合缓存的情况

我从反对缓存开始,因为考虑到当今商品硬件的能力,缓存通常是不必要的。

这就提出了一个问题:为什么几乎所有著名的数据库技术仍然包含一个内部缓存?

答案非常引人入胜,需要探索许多细节。现在,考虑这个反证法:Aerospike,一个没有缓存的数据库,设法达到或甚至超过将部分或全部数据存储在内存中的技术的性能。这清楚地表明,缓存对于实现最佳性能并不是必不可少的。

我同意缓存历来与高性能同义,对于许多人来说,没有缓存层运行数据库的概念似乎不可思议。然而,近年来现代现成硬件的能力,加上 软件开发实践的转变,极大地改变了格局。

例如,现代 SSD 现在可以实现每秒 12 到 14 千兆字节的吞吐量,比十年前常见的旋转磁盘快约 60 倍。这一重大进步尤其值得注意,因为在此期间,我们的 CPU 时钟速度和内存频率基本保持不变。

另一方面,现代软件应用程序在云上运行,并依赖于跨网络的组件间通信。这些网络通常提供高达每秒 12.5 千兆字节的带宽(每秒 100 千兆位)。然而,这个数字仅仅是理论上的。在实践中,我们的网络堆栈中的低效率,包括数据包和帧大小开销、退避和其他因素,使我们无法使用三分之一的容量。

这些变化有两个关键原因。首先,在现代应用程序中,网络而不是磁盘已成为堆栈中最慢的组件。其次,内存和磁盘之间的性能差距已大大缩小;虽然磁盘以前比内存慢两个到三个数量级,但现在它们只慢大约一个数量级。

由于这些原因,在数据库前面部署缓存(无论是内部还是外部)通常效率低下:

  • 外部缓存:必须通过网络访问缓存,与直接内存访问相比,网络通常提供明显更低的吞吐量。这种安排可能导致 RAM 性能能力利用不足。
  • 内部缓存:现代计算机通常包含多个磁盘,这些磁盘共同提供的吞吐量远远超过网络所能处理的吞吐量。因此,从内部缓存获得的额外吞吐量不一定转化为增强的性能。

如本节开头所强调的,如果数据库可以充分利用其可用的所有磁盘吞吐量,则无需将数据缓存在内存中。

适合缓存的情况

在这一点上,您可能认为我对缓存有偏见!事实并非如此。让我提供一些有关缓存何时真正有效的一些指导原则:

  • 存储计算或转换的结果:数据检索有时涉及需要额外 CPU 周期的计算操作或转换。缓存这些计算或转换的结果可以有效地增加应用程序的计算带宽,从而提高整体性能。
  • 小数据集上的高吞吐量:考虑一种情况,您需要管理 400 千兆字节的数据,但需要相当于 10 个磁盘的吞吐量。在这种情况下,使用内存数据库可能是更有效的解决方案。但是,至关重要的是要记住,内存数据库是易失性的。如果数据至关重要,则需要存储支持的内存数据库来防止数据丢失。
  • 提高一系列请求的性能:虽然理想情况下应避免顺序访问,但有时这是不可避免的。在这种情况下,即使缓存命中率非常低,拥有缓存仍然可以增强用户体验。
  • 提高数据局部性:如果源位于远方,将数据缓存到更靠近用户的位置可能会显着降低网络成本。例如,可以将网站的静态组件缓存到更靠近客户的位置,以降低成本并最大程度地减少通过公共互联网跨洲传输数据相关的不稳定性。
  • 消除网络延迟:在应用程序服务器上设置本地缓存可以完全消除网络延迟,从而提高性能。
  • 使用剩余内存:许多应用程序不需要大量的内存,但服务器通常配备充足的内存。将此剩余内存用于缓存可能是有利的。我想强调的是,缓存通常不会造成损害;通常使它们失去优势的是成本效益。只要您不完全依赖添加更多 RAM 作为性能调整策略,利用多余内存进行缓存就是一种不错的方法。
  • 将缓存用作内存数据库:对于始终依赖特定数据部分的应用程序(例如过去一周或一个月的数据),请考虑使用缓存作为内存数据库,以便随时可以使用这些经常访问的数据。
  • 在进程中本地缓存数据:这里稍作解释——本地缓存与本文或前一篇文章的重点没有直接关系。我只是想为读者阐明缓存技术和本地缓存之间的区别。

总结

对于一般用例,考虑使用现代数据库,如高效利用磁盘吞吐量的 Aerospike。这将消除在需要大量内存进行缓存的技术上花费过多资金和资源的需要。除了提供基本数据库功能之外,它还可以配置为内存数据库、存储支持的内存数据库、内存高速缓存或磁盘高速缓存。这种适应性确保了如果您的用例可以从缓存中受益,Aerospike 也可以无缝地满足该需求。

Aerospike 7.1 版本在数据库内核中引入了精密的最近最少使用 (LRU) 缓存逐出,扩展了其驱动企业级内存中缓存用例的能力。在 Aerospike.com 了解更多信息。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注