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子進程)的存在,這個方法不是很適用。
相關文章
相關標籤/搜索