OPcache
什么是 OPcache
Opcache是一种通过将解析的PHP脚本预编译的字节码(Operate Code)存放在共享内存中来避免每次加载和解析PHP脚本的开销,解析器可以直接从共享内存读取已经缓存的字节码(Operate Code),从而大大提高PHP的执行效率
类似于 Java 之类的语言,都是要打包编译之后才能上线运行的,比如打包成一个 jar包 。C++ 或 C# 可以打包成一个 .dll 或 .exe 。这些打包之后的文件就是编译完成的文件,将它们运行起来后一般会一直保持运行状态,也就是会成为一个常驻进程,它们的代码就进入内存中了。在程序运行的时候,不需要再进行解释或编译,自然速度就要快很多。而 OPcache 也是起到类似的作用。只不过它并不是完全的一套编译流程,我们还是依赖的 PHP-FPM 来运行脚本,只不过在开启 OPcache 后,PHP-FPM 会先从内存中查找是否已经有相关的已经缓存的字节码在内存中了,如果有的话就直接取用,如果没有的话,会再次进行解释编译后缓存下来。另外,OPcache 是针对文件的,也就是说,一个文件如果是新增加进来的,只有运行过它才会缓存,如果没有运行过,它并不在当前的共享内存中
Opcache 原理
PHP 的正常执行流程如下
request 请求(nginx,apache,cli 等)–>Zend 引擎读取.php 文件–> 扫描其词典和表达式 –> 解析文件–> 创建要执行的计算机代码 (称为 Opcode)–> 最后执行 Opcode–> response 返回
每一次请求 PHP 脚本都会执行一遍以上步骤,如果 PHP 源代码没有变化,那么 Opcode 也不会变化,显然没有必要每次都重新生成 Opcode,结合在 Web 中无所不在的缓存机制,我们可以把 Opcode 缓存下来,以后直接访问缓存的 Opcode 岂不是更快,启用 Opcode 缓存之后的流程图如下所示:
Opcode cache 的目地是避免重复编译,减少 CPU 和内存开销
Opcache 配置
php.ini
// 加载opcache(需确认已安装opcache拓展)
zend_extension=opcache.so
// 开启opcache
opcache.enable = 1
// OPcache共享内存存储大小,单位MB
opcache.memory_consumption=1024 // 1G
// PHP使用了一种叫做字符串驻留,默认是4MB
opcache.interned_strings_buffer=32
// 这个选项用于控制内存中最多可以缓存多少个PHP文件,这个选项必须得设置得足够大,大于你的项目中的所有PHP文件的总和
opcache.max_accelerated_files=80000
// 设置缓存的过期时间(单位是秒),为0的话每次都要检查
opcache.revalidate_freq=3
// 从字面上理解就是“允许更快速关闭”
opcache.fast_shutdown=1
// CLI环境下,PHP启用OPcache
opcache.enable_cli=1
HugePage
什么是 HugePage
简单的说下就是默认的内存是以4KB分页的,而虚拟地址和内存地址是需要转换的, 而这个转换是要查表的,CPU为了加速这个查表过程都会内建TLB(Translation Lookaside Buffer), 显而易见如果虚拟页越小,表里的条目数也就越多,而TLB大小是有限的,条目数越多TLB的Cache Miss也就会越高, 所以如果我们能启用大内存页就能间接降低这个TLB Cache Miss
配置 HugePage (php.ini
)
这个新特性是做在Opcache里的,所以也要通过Opcache启用这个特性
opcache.huge_code_pages=1
配置OS, 分配一些Hugepages
#切勿越大越好,会长占内存
sudo sysctl vm.nr_hugepages=128
检查内存信息
$ cat /proc/meminfo | grep Huge
AnonHugePages: 444416 kB
HugePages_Total: 128
HugePages_Free: 128
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
看到我们分配的128个Hugepages已经就绪了
Opcache file cache
原理
使用 opcache 把编译后的 php 文件存储为文件,实现 php 源码保护和脚本加速,会有很明显的性能提升
配置(php.ini
)
这样 PHP 就会在 /tmp 目录下 Cache 一些 Opcode 的二进制导出文件,可以跨 PHP 生命周期存在
opcache.file_cache=/tmp
发表评论 取消回复