为什么 APC 会递增“高速缓存满计数”?对于用户缓存,即使它有足够的可用内存?

发布于 2024-09-11 23:57:31 字数 955 浏览 1 评论 0原文

我已经玩了很长一段时间了,但我不知道该怎么做。我在 CentOs 5 上使用 APC 3.1.3p1 和 PHP 5.2.5。 APC 既充当操作码缓存又充当用户缓存。大多数情况下,该服务器使用 CacheRouter 模块来运行 Drupal 6 站点以提供 APC 缓存支持。我运行 APC 3.0.19 一段时间,但它导致 Apache 偶尔锁定(该版本 APC 中记录的错误),所以这就是我使用 3.1.3p1 的原因。

我已将 APC 配置为具有 512 MB 内存 (mmap)。

症状有点间歇性,但从空缓存开始,这通常是我所看到的:

  • 用户缓存填充速度相当慢。尽管初始插入速率约为 20,000 次插入/秒,但用户缓存将仅报告几百个,然后是几千个条目,并且增长速度非常缓慢。我可能会将其归因于 write_locking 处于开启状态,但只是想提一下,以防它对于解决手头的问题很重要。几个小时后,它达到了大约 30k 条目的平衡。

  • 碎片化很早就出现并且增长得很快。在大约 10 小时左右的时间里,我通常会处于 100% 碎片化状态。

  • 总体(操作码 + 用户)缓存使用量稳定在 240MB 左右。它几乎永远不会超过这个水平。大约一天后,我将开始看到用户缓存缓存完整计数 (UCCFC) 递增。

在撰写本文时,我的 UCCFC 为 62358,并且尽管 APC 报告有 280MB 可用空间,但仍在不断增长。我的 user_ttl 为 7200,但我也尝试过将其设置为 0 或其他数量,但它对问题几乎没有影响。

我怀疑这个问题与碎片有关。现在我的服务器报告“碎片:100.00%(24740 个碎片中的 280.0 MB 中的 280.0 MB)”,而 280 MB 恰好是 APC 报告的可用空间量;我认为这是一个明显的巧合。不幸的是,我在文档或其他地方发现了很少的宝贵信息来说明“碎片”在 APC 世界中的真正含义,而且您似乎几乎无法采取任何措施来避免它。

谁能阐明这个问题?

I've played with this for quite a while but am at a bit of a loss as to what to do. I'm using APC 3.1.3p1 on CentOs 5 with PHP 5.2.5. APC is acting as both the opcode cache and user cache. Mostly this server runs Drupal 6 sites using the CacheRouter module for APC cache support. I was running APC 3.0.19 for a while but it was causing Apache to lock up occasionally (a documented bug in that version of APC) so that's why I'm on 3.1.3p1.

I've configured APC to have 512 MBytes of memory (mmap).

The symptoms are a little intermittent but starting from an empty cache this is generally what I see:

  • The user cache fills rather slowly. Despite an initial insert rate of something like 20,000 inserts/sec, the user cache will only report a few hundred, then a few thousand entries, and will grow very slowly. I can possibly attribute this to write_locking being on but just want to mention it in case it's of importance in solving the problem at hand. After several hours it hits an equilibrium of around 30k entries.

  • Fragmentation sets in early and grows quickly. Within maybe 10 hours or so I'm usually at 100% fragmentation.

  • Overall (opcode + user) cache usage stabilizes around 240MB or so. It will virtually never go above that level. After a day or so I'll start seeing the User Cache Cache Full Count (UCCFC) incrementing.

At the time of this writing my UCCFC is at 62358 and growing despite APC reporting 280MB free. I have a user_ttl of 7200, but I've also played with setting it to 0 or other amounts and it has little to no effect on the problem.

I suspect the problem has something to do with fragmentation. Right now my server is reporting "Fragmentation: 100.00% (280.0 MBytes out of 280.0 MBytes in 24740 fragments)" and 280 MB just so happens to be the amount of free space APC is reporting; a telling coincidence, I think. Unfortunately, I've found precious little information in the docs or elsewhere to indicate just what "fragmentation" truly means in the APC world, and there seems to be virtually nothing you can do to avoid it.

Can anyone shed any light on this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千纸鹤 2024-09-18 23:57:31

APC 使用以下公式计算碎片百分比:

(total_size_of_free_blocks_lt_5M / total_size_of_all_free_blocks) * 100

*请注意,它仅将小于 5M 的块计为碎片。

我会将您的具体情况翻译成简单的英语:

碎片:100.00%(24740 个碎片中的 280.0 MB 中的 280.0 MB)

这意味着 280M 的空闲块全部都小于 5M。如果将可用空间除以片段数量,您会发现这相当于平均片段大小约为 11.6K。

这意味着,如果您尝试存储大于所有可用块的项目,它将无法容纳,并且根据 apc.user_ttl 配置设置。如果 TTL 设置为 0,则会刷新整个用户缓存并插入项目。如果 TTL 设置为大于 0,则它将刷新过期条目并插入该条目。在这两种情况下,缓存满计数都会增加。拥有与您的情况一样多的增量表明您可能做错了

以下是一段时间以来碎片对缓存的影响的简单可视化。它代表一个简单的32 Byte缓存大小,每个块是1B。

[--------------------------------] (starts empty)
[A-------------------------------] (1B stored)
[ABB-----------------------------] (2B stored)
[ABBCCCC-------------------------] (4B stored)
... (time elapses)
[A--CCCC-EEE--GGGGGG-III--KKKLLLL]

因此,现在如果您想存储大小为 4B 的项目 M,则不能,因为最大的可用块是 2B。这会触发缓存完整计数增量,以及基于上面详细解释的 user_ttl 的完整或部分刷新。

现在的问题是:这对您来说是坏事吗?

我认为可能是这样。 100% 缓存碎片本身并不坏。在任何运行的生产服务器上看到这种情况并不少见。然而,如果看到它处于 100% 且有那么多可用空间,则表明可能出现问题。

  • 您可能缓存太多;仅仅因为缓存在那里并不意味着您应该将所有内容都推入其中。
  • 您可能使用太短的 TTL(对于条目)进行缓存,低 TTL 意味着非空闲块被更频繁地释放。
  • 您也可能想要存储一些非常大的物品。在 100% 碎片化时,保证任何大于等于 5M 的项目都无法容纳。由于平均可用块大小为 11.6K,给定项目越来越可能不适合,因为它的大小超过 11.6K。

您可能想要尝试按大小对用户缓存进行排序,并查看最大的条目是什么以及它们的 TTL 是多少。也许可以增加?

如果不深入了解您的应用程序和使用模式,实际上不可能给出准确的诊断,但所有这些信息应该让您走上正确的轨道。这很可能不是问题,您可以让 APC 安静地完成工作。

APC calculates the fragmentation percentage using the following formula:

(total_size_of_free_blocks_lt_5M / total_size_of_all_free_blocks) * 100

*Note that it only counts blocks smaller than 5M as fragmented.

I'll translate your specific case into plain english:

Fragmentation: 100.00% (280.0 MBytes out of 280.0 MBytes in 24740 fragments)

This means that of the 280M of your free blocks all of them are less than 5M. If you divide your free space by the number of fragments you'll see that this equates to an average fragment size of ~11.6K.

This means that if you attempt to store an item that is larger than all the available blocks, it will not fit, and one of two things will happen, based on the apc.user_ttl configuration setting. If the TTL is set to 0, then your entire user cache is flushed and the item inserted. If the TTL is set greater than 0 then it will flush expired entries and insert the item. In both of these cases the cache full count gets incremented. Having this increment as much as it is in your case is an indicator that you might be doing it wrong.

Here is a simple visualization of what fragmentation is doing to your cache over time. It represents a simple 32 Byte cache size, each block is 1B.

[--------------------------------] (starts empty)
[A-------------------------------] (1B stored)
[ABB-----------------------------] (2B stored)
[ABBCCCC-------------------------] (4B stored)
... (time elapses)
[A--CCCC-EEE--GGGGGG-III--KKKLLLL]

So now if you want to store item M, which is size 4B, you can't, because the largest available block is 2B. This triggers a cache full count increment, and a full or partial flush based on the user_ttl explained in detail above.

Now the question is: Is this bad in your case?

I think it might be. 100% cache fragmentation isn't bad in and of itself. It's not uncommon to see that on any production server running. However, to see it at 100% with that much free space is a sign that something might be wrong.

  • You could be caching too much; just because the cache is there doesn't mean you should shove everything into it.
  • You could be caching with too short of an TTL (for an entry), low TTLs mean non-free blocks are being freed more often.
  • It's also possible that you have a handful of really large items you're trying to store. At 100% fragmentation it's guaranteed that any item >= 5M won't fit. With your average free block size of 11.6K it's increasingly likely a given item won't fit as it's size increases past 11.6K.

You may want to try sorting your user cache by size and seeing what your biggest entries are, and what their TTLs are. Maybe they could be increased?

It's not really possible to give an exact diagnosis without being elbows deep in your application(s) and the usage patterns, but all of this information should set you on the right track. It's quite possible that it's a non-issue and you can just let APC do it's job quietly.

呆° 2024-09-18 23:57:31

http://pecl.php.net/bugs/bug.php?id= 13146 我认为您应该继续那里或打开一个新的错误报告。

http://pecl.php.net/bugs/bug.php?id=13146 I think you should continue there or open a new bug report.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文