【问题标题】:Caching strategy, when does caching become pointless?缓存策略,什么时候缓存变得毫无意义?
【发布时间】:2011-03-26 08:30:15
【问题描述】:

我对缓存策略和实现还很陌生。我正在开展一个数据库密集型项目,但信息也会定期更新和更改。

我已经找到了足够的信息来大致了解如何开发缓存功能,但我不确定的是一般策略。

如果我缓存所有查询结果并按逻辑事物对它们进行分组,我可以在有意义的触发器上清除它们,我的缓存中可能会有数万个(至少)小文件。只缓存大查询结果会更有意义吗?

我知道这是一个特定于硬件的问题,但一般来说,缓存在多大的文件量下变得毫无意义?这意味着,如果您正在加载包含所有这些小文件的文件系统,那么对它们的访问最终会变得足够慢,以至于您还不如一开始就没有缓存信息?

谢谢大家,我对您提供的任何意见都很感兴趣

编辑:基于关于这绝对是特定于应用程序的响应,让我以这种方式提出这个应该是普遍的问题:

假设我有一个应用程序依赖于一个包含 1,000,000 个项目的表...

进行查询以直接从数据库中检索其中一项,还是从包含 1,000,000 个文件的缓存目录中检索其中一项更快,每个文件都包含其中一项的详细信息?

编辑:显然 100,000 不足以获得有效答案,让我们将其设为 1,000,000。有人想去1,000,000,000吗?因为我能做到……

【问题讨论】:

  • 既然您在征求人们的意见,并且没有比其他解决方案更好的解决方案(至少,在没有指定您的要求和用例的情况下),您可以考虑将其更改为“社区 wiki”。
  • @Michael - 我的用例或要求并不是那么具体。我只是在问,如果我开始将每一条信息都缓存到文件中,那么在某些时候,纯粹的文件量会首先降低缓存带来的性能提升吗?
  • Mysql 应该并且可以在 100k 行这样的小卷上运行得非常快。所以你有足够的性能储备,不会成为缓存狂。
  • 也不要忘记,当你缓存很多时 - 你必须不要忘记缓存失效。失效逻辑是您失去部分缓存优势以及应用程序代码质量/可读性百分比的地方。
  • @Chris,对。您的答案仍会根据文件的大小、读/写频率、支持此功能的系统、运行的硬件而改变。如果您提供一些具有特定要求的特定场景,那么您就有问题了。但是,当您的问题与您的问题一样开放时,社区更喜欢将这些类型的问题作为“wikis”提供,这样的好处是可以提供广泛的答案,而不会影响解决方案的质量。 (meta.stackexchange.com/questions/11740/…)

标签: php mysql caching


【解决方案1】:

使用 MySQL 的内置查询缓存而不是尝试自己维护它。当它们被写入时,它将自动清除对表的缓存查询。另外,它在内存中工作,所以它应该非常高效......

此外,不要只缓存查询。尝试在渲染周期的不同阶段缓存应用程序的整个段。因此,您可以让 MySQL 缓存查询,然后缓存每个单独的视图(渲染)、每个单独的块和每个页面。然后,您可以根据请求选择是否从缓存中提取。

例如,未登录的用户可能会直接从缓存中获取整个页面。但是登录用户可能无法(由于用户名等)。所以对他来说,你可以从缓存中渲染 1/2 的页面视图(因为它们不依赖于用户对象)。您仍然可以获得缓存的好处,但它会根据需要进行分层。

如果您真的期待大量流量,那么绝对值得关注Memcached。让 MySQL 为您存储您的查询,然后将所有用户级缓存项存储在 memcache 中......

编辑:回答您的编辑:

如果单个目录变大,文件系统可能会变慢。只要您按目录“命名空间”(因此每个目录只有一小部分缓存文件),从这个角度来看应该没问题。至于确切的阈值,它实际上取决于您的硬件和文件系统,而不是其他任何东西。我知道如果单个目录中有大量文件,EXT3 会变得非常慢(我的目录实际上包含数十万个文件,而简单地 stat() 其中一个文件可能需要半秒时间,更不用说做任何类型的目录列表)...

但请注意,如果您添加另一台服务器,您将有缓存重复(这不是一件好事),或者将不得不重写整个缓存层。是否有理由不从一开始就选择Memcached

编辑 2:回答您最近的编辑:

调用还是太难了。我有一个应用程序,它的数据库大约有 15 亿行(每天增长大约 50 万行)。我们根本不使用任何缓存,因为我们没有并发问题。即使我们这样做了,我们最好向它扔更多的 MySQL 服务器而不是添加缓存,因为任何形式的缓存都会具有如此低的命中率,以至于不值得花时间添加它。

这就是我坚持不缓存速度的原因。总会有一个对象不在缓存中。因此,如果您使用其中一个对象点击页面,它仍然需要快速。根据经验,我尝试缓存将在接下来的几分钟内再次访问的任何内容(无论如何,我在其他应用程序的生产中保留了大约 5 分钟的生存时间)。因此,如果项目在该时间跨度内获得的点击次数不超过几次,或者命中率非常低(低于 90%),我不会费心缓存该项目....

【讨论】:

  • 谢谢。这正是我好奇的地方。
【解决方案2】:

一般规则是:不需要的时候不要缓存,只缓存需要缓存的东西。

【讨论】:

  • 这是缓存的说法吗,先让它工作,然后担心它有多快?
  • 好的。所以我会把它作为一个选项,只有在事情开始放缓时才打开它。 :) 但是,是否有可能缓存如此多的东西以至于它要么不会提高性能,要么实际上会降低性能?
  • 从不缓存,因为您的应用程序很慢。这是灾难的秘诀。缓存,因为你有太多的负载(意味着太多的并发请求)。但是如果你的应用程序在没有缓存的情况下很慢,添加它只是在枪伤上贴创可贴......如果它很慢,请修复缓慢......
  • @Brian Hooper:完全正确。每个优化(如缓存或更改算法)都非常依赖于上下文。所以一开始的好的解决方案可以进一步给出奇怪的结果。那为什么要浪费时间呢?
  • @ircmaxel - 你在抽什么?
【解决方案3】:

这取决于硬件和应用程序。您需要执行基准测试以确定操作系统索引变得大于数据存储/检索持续时间的阈值(在 MySQL 级别和缓存文件访问级别)。您还需要将其与受众可接受的(非常主观的)阈值进行比较。

【讨论】:

    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2012-09-05
    • 2020-08-03
    • 2011-11-12
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多