PHP的Realpath Cache


PHP的缓存有不少种,包括输出缓冲(ob系列函数),opcode缓存(APC,eAccelerator,XCache等扩展实现),这些你们已经很熟悉了,接下来介绍一下一个不太被人注意的PHP缓存机制:realpath_cache。

介绍

require,require_once,include,include_once这四个语句(并不是函数)你们常常会用到,若是用这类语句去包含文件 (相对路径)的话,那么PHP会去include_path所 指定的路径中去查找相关文件。一个应用中会存在大量的require_once语句调用,若是每次调用都去include_path中查找相应的文件,势 必会对应用的性能产生负面影响。为了不这种负面效应产生的影响,PHPER们会使用文件的绝对路径来包含所需的文件,这样就减小了查询 include_path的次数。

其实,PHP自5.1.0起,就引入了RealpathCache。RealpathCache能够把PHP所用到文件的realpath进行缓存,以便PHP再使用这些文件的时候不须要再去include_path中查找,加快PHP的执行速度。

配置

realpath cache的配置项有两个,分别为realpath_cache_size和realpath_cache_ttl,能够在php.ini中进行修改:

; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
;realpath_cache_size = 16k

; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
;realpath_cache_ttl = 120



其中realpath_cache_size指定了realpath cache的大小,默认为16k,若是你以为这个容量过小,能够适当增长;realpath_cache_ttl指定了缓存的过时时间,默认为120秒, 对于不常常修改的生产环境来讲,这个数字能够调整的更大些。

问题

因为realpath会 展开symlink(即软链接),因此若是你使用修改symlink目标这种方式发布应用的新版本的话,realpath cache会致使一些问题的出现:当你修改symlink使其指向一个新的release目录时候,因为realpath cache所缓存内容尚未过时,因而就会出现应用使用的仍是旧的release,直到realpath cache所缓存内容过时失效为止(默认120秒),或者重启php-fpm。

看个例子:
基础环境:nginx + fastcgi + php-fpm
应用环境:/var/www/app是一个symlink,并作为document_root,在/var/www下存在version0.1,version0.2两个版本的release。初始状况下/var/www/app指向version0.1

lrwxr-xr-x    1 weizhifeng  staff    10 10 22 16:41 app -> version0.1
drwxr-xr-x    3 weizhifeng  staff   102 10 22 16:43 version0.1
drwxr-xr-x    3 weizhifeng  staff   102 10 22 16:43 version0.2



version0.1,version0.2内部各有一个hello.php

[weizhifeng@Jeremys-Mac www]$ cat version0.1/hello.php
<?php
echo 'in version0.1';
?>



[weizhifeng@Jeremys-Mac www]$ cat version0.2/hello.php
<?php
echo 'in version0.2';
?>



nginx配置文件片断:

location / {
            root /var/www/app;   #app为symlink
            index  index.php index.html index.htm;
}

location ~ \.php$ {
            root /var/www/app; #app为symlink
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
}
此时经过HTTP访问hello.php,获得的内容是’in version0.1′;修改/var/www/app,使其指向version0.2 [weizhifeng@Jeremys-Mac www]$ rm -f app && ln -s version0.2/ app 修改完成以后经过HTTP访问hello.php,获得的内容仍旧是”in version0.1″,可见是realpath cache在做祟了,此时你能够重启php-fpm或者等待120秒钟让realpath cache失效。 你能够使用clearstatcache来清 除realpath cache,可是这个只对当前调用clearstatcache函数的PHP进程有效,而其余的PHP进程仍是无效,因为PHP进程池(php-fpm生 成,或者Apache在prefork模式下产生的N个httpd子进程)的存在,这个方法不是很适用。
相关文章
相关标签/搜索