memcached 中出现意外的高“浪费”内存

memcached 中出现意外的高“浪费”内存

已更新,请参阅较长(抱歉)问题的底部。

查看我们的 memcached 统计数据,我想我发现了一个我之前没有意识到的问题。似乎我们浪费的空间非常多。我检查了一下phpmemcache管理工具变化,发现这张图片盯着我:

memcached 缓存大小图表

现在我的印象是,最坏的情况是浪费 50%,尽管我承认我并不了解所有的细节。我读过——其中包括——这一页它确实有些老旧,但我们的 memcached 版本也一样。我想我确实了解系统是如何工作的(例如)我相信,但我很难理解我们如何才能达到 76% 的浪费空间。

phpmemcacheadmin 显示的驱逐率为2 ev/s,因此这里存在一些问题。

  • 主要问题是:我该怎么做才能解决这个问题。我可以给它投入更多内存(我认为还有一些额外的内存可用),也许我应该摆弄 slab 配置(这个版本是否可行?),也许还有其他选择?升级 memcached 版本不是一个快速可用的选项。

  • 出于好奇,第二个问题当然是,预计空间浪费率是否会达到 75%(并且还在上升),如果是,为什么。

系统:目前我对此无能为力,我知道 memcached 版本不是最新的,但这是我已经处理好的局面。

  • Memcached 1.4.5
  • Apache 2.2.17
  • PHP 5.3.5

作为对 @DavidSchwartz 的回答的回应:这里是 phpmemcacheadmin 生成的 slab 统计数据:(顺便说一下,还有更多的 slab)

我还在此处以文本格式粘贴了稍后的统计数据

楼板细节

更新

我用 -f 1.5 重启了守护进程,结果看起来非常好。经过一段时间的预热后,我们的使用量/浪费量为 50/50。但是,和以前一样,随着白天时间的延长(白天越来越忙),它开始回落到目前的水平:30/70,而浪费量仍在上升。除此之外,我仍然不知道“浪费”来自哪里。我看到了这块板:

**Slab 5 Stats**
Chunk Size  496.0 Bytes
Used Chunk  77502 [24.6 %]
Total Chunk 314986
Total Page  149
Wasted      117.3 MBytes
Hits        30.9 Request/sec
Evicted     0

它不是满的,也没有被驱逐,但它浪费了 117.3 MB。我做了一个快速计算(如果我错了请纠正我)是:

  • 前一个 slab 的块大小为 328,因此最坏的情况是该 slab 将填充 329 字节的块。
  • 这意味着每个使用的块浪费 167 字节 = 12942834 字节 = 12.3 MB

那么另一个在哪里浪费了 105 MB来自哪里?它旁边的大哥哥是这样的:

**Slab 6 Stats** 
Chunk Size  744.0 Bytes
Used Chunk  17488 [31.0 %]
Total Chunk 56360
Total Page  40
Wasted      31.1 MBytes
Hits        107.7 Request/sec
Evicted     1109

答案1

这个问题已经提出一年了,我不知道你是否找到了答案,但我要说的是,你对“浪费”的看法是错误的。

浪费的内存在内存中分配,因此不能被其他应用程序使用,但它仍然可供 memcached 使用。

为了简化解释,假设您有一个具有 3MB RAM 和 3 个 Slab 的 memcache:

slab class  1: chunk size     10485 perslab      100
slab class  2: chunk size    104857 perslab       10
slab class  3: chunk size   1048576 perslab        1

执行一个大小为 10k 的“集合”。您会在统计数据中(大致)看到:

0.03% used
66.6% free
33% wasted

这是因为 memcached 从“slab class 1”中分配了一个单独的块,并且该 slab 的 99% 的内存被“浪费”而 1% 被“使用”这并不意味着该 slab 和为该 slab 分配的内存已经消失。

执行另一个大小为 10k 的单个“集合”。这次您将看到:

0.06% used
66.6% free
32.7% wasted

因此现在您正在使用 slab 1 中分配的 100 个块中的 2 个,“浪费”的统计数据下降了,而使用的统计数据增加了。

used% + wasted% 等于 100% 并没有什么问题。这并不意味着您没有剩余内存,它只是意味着您从每个 slab 中分配了至少一个块。

要查看此问题,请使用一个 100k 大小的“集合”和另一个 1000k 大小的“集合”

现在你会看到

36.6% used
   0% free
63.3% wasted

答案2

您可能拥有大量非常小的对象。通常,最小的 slab 可容纳 104 字节条目。如果您有很多条目只是将一个整数映射到另一个整数,则浪费率可能高达 85%。

您可以在文章中找到有关如何调整此问题的信息Memcached 用于小对象

答案3

我遇到了这个问题,并从 memcached 移到了 redis(没有基于磁盘的保存)。我知道这可能不可行,但你可以尝试一下,并密切关注内存碎片。你甚至可以打开持久性来修复重启时的“旧缓存”问题。

相关内容