密钥到期前的Memcached驱逐?

时间:2011-07-29 03:09:48

标签: memcached

如果仍有可用空间,那么存储在memcached中的键/值对是否可以在其到期之前被驱逐?

我运行的memcached进程允许消耗高达6GB;据报道,2.5GB正在使用中,而且这个数字波动很小(一天内+/- 100MB)。如果我设置一个在15分钟内到期的简单字符串值,是否有可能在15分钟之前将其逐出(cache.get返回未找到)?

谢谢, -Eric

2 个答案:

答案 0 :(得分:35)

基本上,memcache在chuncks和on-demand中分配空间,然后将项目存储到块中并手动管理该内存。因此,较小的项目可以“使用”比在每个项目上分配空间时更大的内存。

该链接比我更好地解释了它

https://groups.google.com/group/memcached/browse_thread/thread/8f460034418262e7?pli=1

修改:添加更多解释

Memcache通过分配各种大小的slab来工作。这些板有许多特定尺寸的槽(由板的类决定)。

假设(并且仅使用我对Memcache内部的抽象),假设最小尺寸的平板类是1K。这意味着最小的插槽是1K。此外,Memcache一次只能以1024或1MB的内存分配这些内存。可以说我们有这样的配置,我们想将一个1字节的对象(char值?)存储到Memcache中。让我们假设这需要5个字节的内存(4字节密钥?)。在空缓存中,Memcache将分配一个最小大小的新slab,它可以保存该值(1K个槽)。因此,存储5个字节将导致Memcache分配1MB内存。

现在,假设你有很多这些。接下来的1023将是“免费的” - Memcache已经分配了内存,因此不需要额外的内存。在这结束时,你已经存储了1024 * 5字节= ~5KB,但Memcache使用1MB来存储它。存储几百万这些,你可以想象消耗千兆字节的内存来存储千字节的数据。

这接近最坏的情况。在实践中,Memcache可以配置为在需要时具有非常小的最小平板类大小,并且可以扩大或缩小增长因子(平板类之间的大小差异)。如果您正在缓存数据库查询,则可能有大小从几个字节到几KB的项目,页面内容甚至可以进入MB。

这是关键点 Memcache不会回收内存或清理平板(新版本现在确实有这个非常重要的性能命中,但传统上,这就是Memcache的工作原理)。

假设您有一个已经愉快地运行和缓存几天的系统。你有数以百计的各种尺寸的板坯。您可以在不重置缓存的情况下将新的页面缓存策略部署到应用程序。现在,您不是缓存整个页面,而是缓存页面的一部分。你已经改变了你的缓存模式,从存储大量的~1MB对象到存储大量~10KB的对象。这就是我们遇到麻烦的地方。 Memcache已经分配了一堆容纳大约1MB对象的平板。您以前从未使用过缓存许多10KB对象。具有10KB插槽的平板很快就会被填满,但现在你有一大堆已分配的平板,它们可以容纳1MB的未被使用的对象(没有其他东西那么大)。 Memcache不会将你的10KB对象放在1MB的插槽中(即使它确实如此,它也不会有太长的帮助)。它需要获得更多容纳10KB对象的slab,但它不能,因为所有内存都已分配到容纳1MB对象的slab中。结果是,您可以在平板中分配可能的千兆字节内存,以容纳1MB对象,这些对象在您的10KB插槽板已满时处于空闲状态。在这种情况下,尽管有几千兆字节处于闲置状态,您仍将开始从10KB插槽板中逐出物品。

这是一个冗长,做作,极端的例子。您的缓存策略很少会如此明显地变化或显着变化。 slab-classes的默认增长因子是1.25,所以你有1KB插槽,1.25KB插槽,1.5KB插槽等等。这个概念成立 - 如果你大量使用某些大小的平板并且模式转换(sql)查询返回更多的对象?网页变得更大?向表中添加一个列,将缓存的响应移动到一个slab类?等等)然后你可以得到一堆“错误”的大小的平板,你可以拥有尽管拥有千兆字节的“未使用”空间,但“无处”存储了一些东西。

如果你正在进行驱逐,可以远程登陆Memcache并找出造成驱逐的平板。通常,缓存重置(是的,清空一切)解决了这个问题。这是关于如何获得统计数据的参考。 http://lzone.de/articles/memcached.htm

答案 1 :(得分:3)

Memcached根据不同内存块的slab存储数据。如果已经分配了不同的内存块,那么即使其他内存块中没有数据,最近使用的最小算法也会在平板上运行并逐出数据。

因此,数据大小的大量分布可能导致此问题。通过让多个memcached实例运行并将其用作分布式系统,可以减少问题。