我们尝试在高负载环境中部署 APC 用户缓存作为我们的中央缓存服务 (redis) 的每台服务器上的本地第二层缓存,用于缓存几乎不更改结果的数据库查询和配置。我们基本上看看 Facebook 做了什么(几年前):
http://www.slideshare.net/guoqing75/4069180-caching-performance-lessons-from-facebook http://www.slideshare.net/shire/php-tek-2007-apc-facebook
它在一段时间内运行良好,但在高负载下几个小时后,APC 遇到问题,因此整个 mod_php 不再执行任何 PHP。即使是一个简单的 PHP 脚本也不再响应,而静态资源仍然由 Apache 提供。它并没有真正崩溃,没有段错误。我们尝试了最新的稳定版和最新的 APC 测试版,我们尝试了 pthreads、自旋锁,每次都遇到同样的问题。我们为 APC 提供了它可以消耗的更多内存,在崩溃前 1 分钟,我们有 2% 的碎片,大约 90% 的内存是空闲的。当它“崩溃”时,我们在错误日志中找不到任何东西,只有重新启动 Apache 会有所帮助。只有使用自旋锁,我们才会得到一个 php 错误,即:
PHP致命错误:未知:在第0行的未知中检测到卡住的自旋锁(0x7fcbae9fe068)
这似乎是一种超时,pthread 不会发生这种情况,因为它们不使用超时。
发生的事情可能是这样的:http: //notmysock.org/blog/php/user-cache-timebomb.html
一些数字:服务器每秒有大约 400 个 APC 用户缓存命中和大约 30 次插入(我认为这是很多),一个请求有大约 20-100 个用户缓存请求。用户缓存中大约有 300.000 个变量,所有变量都带有 ttl(我们只在中央 redis 中存储不带 ttl 的变量)。
我们的 APC 设置是:
apc.shm_segments=1
apc.shm_size=4096M
apc.num_files_hint=1000
apc.user_entries_hint=500000
apc.max_file_size=2M
apc.stat=0
目前我们使用的是用自旋锁编译的 3.1.13-beta 版本,与旧的 PHP 5.2.6 一起使用(这是一个遗留应用程序,我听说这个 PHP 版本也可能有问题?),Linux 64 位。
调试起来真的很困难,我们编写了监控脚本,这些脚本每分钟从 apc、系统等处收集尽可能多的数据,但我们看不到任何异常情况——即使在崩溃前 1 分钟也是如此。
我在这里看到了很多类似的问题,但是到目前为止我们还没有找到解决我们问题的解决方案。当我读到这样的东西时:
http://webadvent.org/2010/share-and-enjoy-by-gopal-vijayaraghavan
我不确定将 APC 用于本地用户缓存是否是高负载环境中的最佳选择。我们已经在这里使用过 memcached,但是 APC 要快得多。但是如何让它稳定呢?
最好的问候,安德烈亚斯