分析eaccelerator的opcode缓存功能

PHP脚本的执行在内部是有编译和运行两个流程中,具体是第一步把PHP脚本编译产出 opcode中间码,第二步是在Zend Engine上执行opcode中间码,如下图所示。正因为存在这个两步的过程,所以在生产环境中,一般都会采用opcode cache的方式,较少PHP脚本的编译过程,从而提升PHP的运行性能。其中比较流行的opcode cache工具有eacceleratorapcxcache等。eaccelerator是其中比较典型的一款,当然eaccelerator也有单机cache的功能。本文主要深入eaccelerator的opcode cache缓存过程。

PHP执行流程

 

Eaccelerator的原理和分析结论

Eacc是一个标准的opcode cache + 共享内存单机cache。其中关于opcode cache部分的实现关键是采用eaccelerator_compile_file替换PHP原有的zend_compile_file。众所周 知,PHP内部执行流程是:PHP代码->编译产出opcode-》执行opcode,这么个三步走,其中opcode cache就是节省掉PHP编码的编译过程。

在Eaccelerator的内部也是按照这个步骤来做的。为了提高大家阅读效率,首先介绍下分析后的几个结论:

  1. eaccelerator的opcode cache方式有两种,内存+硬盘文件。
  2. 一个php文件对应一个opcode cache。也就是说opcode cache不会进行文件级别的meger。
  3. 无论是多进程和多线程,1个php文件只会对应唯一一个opcode cache。不会说多进程则对应多个。由于有读写检查和冲突,所以不可避免的会引入锁。(在apc中会有一个开关,进行是否开启更新检查。eaccelerator目前看起来没有)
  4. 特别需要注意一点,在加载opcode cache的时候,是需要首先通过opcode重建类、方法到对应的符号表的(具体可以参考大话PHP之性能中的分析)。
  5. eaccelerator的锁在多进程模式下是自旋锁。(通常的php-fpm、apache下的prefork模式都是这种)。
  6. eaccelerator的锁在多线程模式下是线程锁+自旋锁。(通常对应apache的worker模式)

由于这些锁和一些opcode cache更新的检查,会给PHP带来一定的性能开销(从目前初步测试来看,无论是多进程和多线程都回有不小的影响)。具体数据后续会给出。正因为这些数据,后续有考虑把PHP的编译和执行直接分成两个步骤来做。

ok,据此,我们重点分析下eaccelerator_compile_file函数。

摘自:http://blog.xiuwz.com/2011/12/29/%E6%B7%B1%E5%85%A5%E5%88%86%E6%9E%90eaccelerator%E7%9A%84opcode%E7%BC%93%E5%AD%98%E5%8A%9F%E8%83%BD/

相关文章
相关标签/搜索