IT技术博客大学习 共学习 共进步

前端开发中的性能那点事(三)php的opcode缓存

搜索技术博客-淘宝 2010-12-30 22:43:09 浏览 2,902 次

前言:由php的运行机制决定,其实php在运行阶段我们也是可以进行缓存的从而提高程序运行效率,这就是我们常说的opcode缓存。
1、简述php的运行机制
(因为本文是写opcode缓存的所以这里只是简要概述,后边会专门写一篇揭秘php运行机制的。)
a).php文件通过浏览器过来
b)请求交给SAPI,随后SAPI层将控制权转给PHP
c)zend_language_scanner对代码进行扫描,对php代码进行词法分析转换成一系列的tokens array
d)zend_language_parser将c步骤产生的一系列tokens处理掉空格等无用的代码以后转换成一系列表达式
e)经过compiler阶段生成opcode返回zend_op_array指针
f)zend_vm_execute根据传入的zend_op_array指针,执行opcode并将结果返回输出
(下图来自互联网,但是描述的很不错借花献佛了)

2、opcode简介
Opcode是operation code(操作码)的简称,其实就是第一小节c)、d)、e)步骤产生的一种中间码,
opcode是一个四元组,(opcode, op1, op2, result),它们分别代表操作码,第一操作数,第二操作数,结果。
如:

 
1 <?php
2 echo "taobao search blog";
3 ?>

对应的tokens

 
01 Array
02 (
03     [0] => Array
04         (
05             [0] => 367
06             [1] => <?php
07             [2] => 1
08         )
09   
10     [1] => Array
11         (
12             [0] => 316
13             [1] => echo
14             [2] => 1
15         )
16   
17     [2] => Array
18         (
19             [0] => 370
20             [1] =>
21             [2] => 1
22         )
23   
24     [3] => Array
25         (
26             [0] => 315
27             [1] => "taobao search blog"
28             [2] => 1
29         )
30   
31     [4] => ;
32     [5] => Array
33         (
34             [0] => 370
35             [1] =>
36             [2] => 1
37         )
38   
39     [6] => Array
40         (
41             [0] => 369
42             [1] => ?>
43             [2] => 1
44         )
45   
46 )

对应的opcode就是

 
1 line     # *  op                           fetch          ext  return  operands
2 ---------------------------------------------------------------------------------
3    2     0  >   ECHO                                                     'taobao+search+blog'
4    4     1    > RETURN                                                   1
5          2*   > ZEND_HANDLE_EXCEPTION

3、使用apc对opcode缓存
a)假设php路径为/home/ad/php
对opcode进行缓存的软件很多(apc、eAcclerator、Xcache、Zend Platform),这里主要介绍apc
APC提供两种缓存功能,即缓存Opcode(目标文件),我们称之为apc_compiler_cache。同时它还提供一些接口用于PHP开发人员将用户数据驻留在内存中,我们称之为apc_user_cache。我们这里主要讨论apc_compiler_cache的配置。
下载地址:http://pecl.php.net/package/APC
最新版本为APC-3.1.6.tgz

 
1 wget http://pecl.php.net/get/APC-3.1.6.tgz
2 tar -zxvf APC-3.1.6.tgz
3 cd APC-3.1.6
4 /home/ad/php/bin/phpize
5 ./configure --enable-apc --enable-apc-mmap  --with-php-config=/home/ad/php/bin/php-config
6 make
7 make install

编辑php.ini
添加apc的配置

 
01 [apc]
02 extension=apc.so
03 apc.enabled=1
04 apc.shm_segments = 1
05 apc.shm_size = 128
06 apc.ttl = 0
07 apc.user_ttl = 7200
08 apc.num_files_hint = 1000
09 apc.write_lock=1
10 apc.stat = 0
11 apc.max_file_size=1M
12 apc.filters = a.php,b.php
13 apc.cache_by_default=1

重新apache就ok啦

4、常用参数的解析
apc.enabled 开启apc 设置为0关闭,1为开启
apc.shm_segments 共享内存块数
apc.shm_size 共享内存大小,但是是M
那么显然共享内存的总数就是apc.shm_segments*apc.shm_size
apc.num_files_hint 允许多少个opcode被缓存
apc.stat 为1的时候会自动检查opcode对应的php文件是否有更新,有更新的话会自动更新。设置为0的话就不会去检查了这样会提高apc的效率,但是要使php的修改生效的话就必须重启apache了,或者使用函数apc_cache_clear()来清空缓存
apc.ttl opcode缓存的过期时间,设置为0表示不过期,如果不为0会检查两次请求之间的时间,如果时间大于设置值那么会更新opcode缓存
apc.write_lock 表示多个进程同时更新一份opcode缓存的时候那么只让最先的一个生效,可以有效避免写冲突
apc.max_file_size 超过设置值大小的文件不被缓存
apc.filters 需要特例的文件,多个文件用逗号(,)相隔
apc.filters 与 apc.cache_by_default结合使用,
当apc.cache_by_default为1时apc.filters文件不被缓存,当apc.cache_by_default为0时仅apc.filters文件被缓存

5、下期预告:(四)使用数据缓存memcache

建议继续学习

  1. 浅析http协议、cookies和session机制、浏览器缓存 (阅读 17,203)
  2. 分布式缓存系统 Memcached 入门 (阅读 16,042)
  3. 强制刷新本地 DNS 缓存记录 (阅读 10,640)
  4. 发布一个查看PHP opcode的扩展模块及Web服务 (阅读 8,284)
  5. php缓存与加速分析与汇总 (阅读 7,723)
  6. Web应用的缓存设计模式 (阅读 7,304)
  7. 浏览器缓存机制 (阅读 7,100)
  8. 使用memc-nginx和srcache-nginx构建高效透明的缓存机制 (阅读 6,941)
  9. 谈冷热数据 (阅读 6,882)
  10. 缓存设计的一些思考 (阅读 6,820)