Road to growth of rookie

Meaningful life is called life

0%

Opcache 最佳设置

在网上无意中看到的一篇 文章, 这哥们非常简洁地谈论了 Zend Opcache 的最佳设置, 他说他为此花了大量的时间探索 Zend Opcache 的每个设置选项的细节, 甚至是阅读它的源代码, 并且在自己的项目中实践 (一个每天有 117 millionHTTP 请求的应用) . 个人觉得这种文章相当有指导意义, 所以特地把它的设置方式摘译如下 (格式有些修改).

1
opcache.revalidate_freq

这个选项用于设置缓存的过期时间 (单位是秒), 当这个时间达到后, Opcache 会检查你的代码是否改变, 如果改变了 PHP 会重新编译它, 生成新的 Opcode, 并且更新缓存. 值为 “0” 表示每次请求都会检查你的 PHP 代码是否更新 (这意味着会增加很多次 PHP 系统调用, 译注: stat 系统调用是读取文件的状态, 这里主要是获取最近修改时间, 这个系统调用会发生磁盘 stat, 所以必然会消耗一些 stat 时间, 当然系统调用本身也会消耗一些 CPU 时间) . 可以在开发环境中把它设置为 0, 生产环境下不用管, 因为下面会介绍另外一个设置选项.

1
opcache.validate_timestamps

当这个选项被启用 (设置为 1) , PHP 会在 opcache.revalidate_freq 设置的时间到达后检测文件的时间戳 (timestamp) .

如果这个选项被禁用 (设置为 0) , opcache.revalidate_freq 会被忽略, PHP 文件永远不会被检查. 这意味着如果你修改了你的代码, 然后你把它更新到服务器上, 再在浏览器上请求更新的代码对应的功能, 你会看不到更新的效果, 你必须得重新加载你的PHP (使用 kill -SIGUSR2 强制重新加载) .

这个设定是不是有些蛋疼, 但是我强烈建议你在生产环境中使用, 为啥?因为当你在更新服务器代码的时候, 如果代码较多, 更新操作是有些延迟的, 在这个延迟的过程中必然出现老代码和新代码混合的情况, 这个时候对用户请求的处理必然存在不确定性.

1
opcache.max_accelerated_files

这个选项用于控制内存中最多可以缓存多少个 PHP 文件. 这个选项必须得设置得足够大, 大于你的项目中的所有 PHP 文件的总和. 我的代码库大概有 6000 个 PHP 文件, 所以我把这个值设置为一个素数 7963 (译注: 不知道这哥们为什么要设置这个数, 7963 也不是大于 6000 的最小素数) .

你可以运行 find . -type f -print | grep php | wc -l 这个命令来快速计算你的代码库中的PHP文件数.

1
opcache.memory_consumption

这个选项的默认值为 64MB, 我把它设置为 192MB, 因为我的代码很大. 你可以通过调用 opcachegetstatus() 来获取 Opcache 使用的内存的总量, 如果这个值很大, 你可以把这个选项设置得更大一些.

1
opcache.interned_strings_buffer

这是一个很有用的选项, 但是似乎完全没有文档说明. PHP 使用了一种叫做字符串驻留 (string interning) 的技术来改善性能. 例如, 如果你在代码中使用了 1000 次字符串 foobar, 在 PHP 内部只会在第一使用这个字符串的时候分配一个不可变的内存区域来存储这个字符串, 其他的 999 次使用都会直接指向这个内存区域. 这个选项则会把这个特性提升一个层次——默认情况下这个不可变的内存区域只会存在于单个 php-fpm 的进程中, 如果设置了这个选项, 那么它将会在所有的 php-fpm 进程中共享. 在比较大的应用中, 这可以非常有效地节约内存, 提高应用的性能.

这个选项的值是以兆字节 (megabytes) 作为单位, 如果把它设置为 16, 则表示 16MB, 默认是 4MB, 这是一个比较低的值.

1
opcache.fast_shutdown

另外一个很有用但也没有文档说明的选项. 从字面上理解就是 允许更快速关闭. 它的作用是在单个请求结束时提供一种更快速的机制来调用代码中的析构器, 从而加快 PHP 的响应速度和 PHP 进程资源的回收速度, 这样应用程序可以更快速地响应下一个请求. 把它设置为 1 就可以使用这个机制了.

最终我们对于 Opcachephp.ini 的设置如下:

1
2
3
4
5
6
opcache.revalidate_freq=0
opcache.validate_timestamps=0 ;在开发环境可以把这一行注释掉
opcache.max_accelerated_files=7963
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1

参考资料