结合缓存方法 - 基于memcache / disk

时间:2010-03-24 18:30:08

标签: database caching scalability memcached

这是交易。我们将采用完整的静态html之路解决性能问题,但由于该网站将部分动态,这对我们来说无法解决。 我们所想到的是使用memcache + eAccelerator来加速PHP并处理最常用数据的缓存。

以下是我们现在想到的两种方法:

  • 在>>所有<<上使用memcache重大疑问,不管它做什么最好。

  • 用于最常检索数据的Usinc内存缓存,并与标准的硬盘存储缓存相结合以供进一步使用。

仅使用内存缓存的主要优点当然是性能,但随着用户的增加,内存使用量会增加。将这两种声音结合起来对我们来说就像一种更自然的方法,即使理论在性能上有所妥协。 Memcached似乎也有一些复制功能,在增加节点时可能会派上用场。

我们应该采用什么方法? - 妥协和结合这两种方法是愚蠢的吗?我们是否应该专注于使用内存缓存,而是在负载随用户数量增加的情况下专注于升级内存?

非常感谢!

5 个答案:

答案 0 :(得分:4)

我认为妥协和结合这两种方法是一种非常聪明的方法。

最明显的缓存管理规则是延迟vs.大小规则,也用于CPU缓存。在多级缓存中,每个下一级别应具有更大的大小以补偿更高的延迟。我们有更高的延迟但更高的缓存命中率。所以,我不建议你把基于磁盘的缓存放在memcache前面。 С相反它应该放在memcache后面。唯一的例外是如果缓存挂载在内存中的目录(tmpfs)。在这种情况下,基于文件的缓存可以补偿内存缓存的高负载,并且还可能具有延迟利润(因为数据位置)。

这两个存储(基于文件,内存缓存)不仅是便于缓存的存储。您也可以使用几乎任何KV数据库,因为它们非常擅长并发控制。

缓存失效是一个独立的问题,可引起您的注意。您可以使用几种技巧在缓存未命中时提供更细微的缓存更新。其中之一是狗堆效应预测。如果几个并发线程同时获得高速缓存未命中,则所有这些线程都进入后端(数据库)。应用程序应该只允许其中一个继续,其余的应该等待缓存。其次是后台缓存更新。不是在Web请求线程中而是在后台更新缓存是很好的。在后台,您可以更优雅地控制并发级别并更新超时。

实际上有一种很酷的方法可以让你进行基于标记的缓存跟踪(例如memcached-tag)。引擎盖下非常简单。对于每个缓存条目,您可以保存它所属的标记版本的向量(例如:{directory#5: 1, user#8: 2})。当您读取缓存行时,您还会从memcached读取所有实际的向量编号(这可以使用multiget有效执行)。如果至少一个实际标签版本大于缓存行中保存的标签版本,则缓存无效。当您更改对象(例如目录)时,应增加适当的标记版本。这是一种非常简单而有效的方法,但它有自己的缺点。在此方案中,您无法执行有效的缓存失效。 Memcached可以轻松删除实时条目并保留旧条目。

当然你应该记住:“计算机科学只有两件事:缓存失效和命名事物” - Phil Karlton。

答案 1 :(得分:3)

Memcached是一个非常可扩展的系统。例如,您可以复制缓存以减少某些密钥桶的访问时间,或实现Ketama算法,使您能够从池中添加/删除Memcached实例,而无需重新映射所有密钥。通过这种方式,当您碰巧有额外的内存时,您可以轻松添加专用于Memcached的新机器。此外,由于其实例可以以不同的大小运行,因此可以通过向旧机器添加更多RAM来抛出一个实例。通常,这种方法更经济,并且在某种程度上不逊于第一种方法,特别是对于 multiget()请求。关于数据增长的性能下降,Memcached中使用的算法的运行时间不随数据大小而变化,因此访问时间仅取决于同时请求的数量。最后,如果要调整内存/性能优先级,可以设置过期时间和可用内存配置值,这将严格使用RAM或增加缓存命中率。

同时,当您使用硬盘时,文件系统可能会成为您应用程序的瓶颈。除了一般的I / O延迟之外,诸如碎片和巨大目录之类的东西会显着影响您的整体请求速度。另外,请注意默认Linux硬盘设置的兼容性比速度更高,因此建议在使用前正确配置(例如,您可以尝试 hdparm 实用程序)。

因此,在添加一个更多的集成点之前,我认为你应该调整现有的系统。通常,正确设计的数据库,配置PHP,Memcached和处理静态数据应该足够用于高负载的网站。

答案 2 :(得分:2)

我建议您首先对所有主要查询使用memcache。然后,测试以查找最少使用的查询或很少更改的数据,然后为此提供缓存。

如果您可以将常用数据与很少使用的数据隔离开来,那么您可以专注于提高更常用数据的性能。

答案 3 :(得分:2)

当您确定需要时,可以使用Memcached。您不必担心内存会很重,因为在评估它时,您需要包含要部署它的专用框的成本。

在大多数情况下,将memcached放在共享计算机上是浪费时间,因为它的内存将更好地用于缓存其他任何内容。

memcached的好处是你可以将它用作许多机器之间的共享缓存,从而提高命中率。此外,您可以使缓存大小和性能高于单个框可以提供,因为您可以(并且通常会)部署多个框(每个地理位置)。

此外,通常使用memcached的方式取决于应用服务器的低延迟链接;因此,您通常不会在基础架构中的不同地理位置使用相同的memcached群集(每个DC都有自己的群集)

过程是:

  1. 识别性能问题
  2. 决定性能改善程度是否足够
  3. 在您的测试实验室,使用必要的驱动程序机器的生产级硬件上重现问题 - 这非常重要,您可能需要大量专用(甚至是专用)硬件来充分驱动您的应用程序。
  4. 测试建议的解决方案
  5. 如果有效,请将其发布到生产环境,如果没有,请尝试更多选项并重新开始。
  6. 你不应该

    • 缓存“一切”
    • 在不衡量实际影响的情况下做事。

    由于您的性能测试环境永远不会完美,您应该拥有足够的仪器/监控功能,以便衡量性能并在生产中分析您的应用。

    这也意味着您缓存的每一件事都应该有一个缓存命中/未命中计数器。您可以使用它来确定何时浪费缓存。如果缓存的命中率较低(比如说<90%),则可能不值得。

    在生产中可以切换单个缓存也是值得的。

    记住:OPTIMISATIONS引入功能性错误。做尽可能少的优化,并确保它们是必要且有效的。

答案 4 :(得分:1)

您可以将磁盘/内存缓存的组合委派给操作系统(如果您的操作系统足够智能)。 对于Solaris,您实际上甚至可以在中间添加SSD层;这项技术被称为L2ARC。

我建议您先阅读此内容:http://blogs.oracle.com/brendan/entry/test