1、APC緩存簡介
php
APC,全稱是Alternative PHP Cache,官方翻譯叫」可選PHP緩存」。它爲咱們提供了緩存和優化PHP的中間代碼的框架。 APC的緩存分兩部分:系統緩存和用戶數據緩存。node
系統緩存正則表達式
它是指APC把PHP文件源碼的編譯結果緩存起來,而後在每次調用時先對比時間標記。若是未過時,則使用緩存的中間代碼運行。默認緩存apache
3600s(一小時)。可是這樣仍會浪費大量CPU時間。所以能夠在php.ini中設置system緩存爲永不過時(apc.ttl=0)。不過若是這樣設置,改運php代碼後須要重啓WEB服務器。目前使用較多的是指此類緩存。數組
用戶數據緩存緩存
緩存由用戶在編寫PHP代碼時用apc_store和apc_fetch函數操做讀取、寫入的。若是數據量不大的話,能夠一試。若是數據量大,使用相似memcache此類的更加專著的內存緩存方案會更好php框架
緩存key生成規則服務器
APC的緩存中的每一個slot都會有一個key,key是網絡
apc_cache_key_t結構體類型,除了key相關的屬性,關鍵是h字段的生成。 h字段決定了此元素落於slots數組的哪個位置。對於用戶緩存和系統緩存,其生成規則不一樣。 用戶緩存經過apc_cache_make_user_key函數生成key。經過用戶傳遞進來的key字符串,依賴PHP內核中的hash函數(PHP的hashtable所使用的hash函數:zend_inline_hash_func),生成h值。框架
系統緩存經過apc_cache_make_file_key函數生成key。經過APC的配置項apc.stat的開關來區別對待不一樣的方案。在打開的狀況下,即
apc.stat= On 時,若是被更新則自動從新編譯和緩存編譯後的內容。此時的h值是文件的device和inode相加所得的值。在關閉的狀況下,即apc.stat=off時,當文件被修改後,若是要使更新的內容生效,則必須重啓Web服務器。此時h值是根據文件的路徑地址生成,而且這裏的路徑是絕對路徑。即便你是使用的相對路徑,也會查找PG(include_path)定位文件,以取得絕對路徑,因此使用絕對路徑會跳過檢查,能夠提升代碼的效率。
添加緩存過程
以用戶緩存爲例,apc_add函數用於給APC緩存中添加內容。若是key參數爲字符串中,APC會根據此字符串生成key,若是key參數爲數組,APC會遍歷整個數組,生成key。根據這些key,APC會調用_apc_store將值存儲到緩存中。因爲這是用戶緩存,當前使用的緩存爲apc_user_cache。執行寫入操做的是apc_cache_make_user_entry函數,其最終調用apc_cache_user_insert執行遍歷查詢和寫入操做。與此對應,系統緩存使用apc_cache_insert執行寫入操做,其最終都會調用_apc_cache_insert。
不論是用戶緩存仍是系統緩存,大致的執行過程相似,步驟以下:
經過求餘操做,定位當前key的在slots數組中的位置: cache->slots[key.h % cache->num_slots];
在定位到slots數組中的位置後,遍歷當前key對應的slot鏈表,若是存在slot的key和要寫入的key匹配或slot過時,清除當前slot。
在最後一個slot的後面插入新的slot。
2、APC模塊安裝
A.WINDOWS下安裝APC
第一步:下載php_apc.dll 在http://pecl.php.net/package/apc 要與php版本對應 將php_apc.dll放入你的ext目錄
第二步:讓php.ini支持apc擴展模塊。 而後打開php.ini 加入:
extension=php_apc.dll apc.rfc1867 = on apc.max_file_size = 100M upload_max_filesize = 100M post_max_size = 100M //以上參數可本身定義
第三步:檢查是否支持PHP APC apc_store apc_fetch
查看phpinfo中是否有apc相關項
B.LIUNX下安裝APC
第一步:下載和安裝
wget http://pecl.php.net/get/APC-3.1.8.tgz tar -zxvf APC-3.1.8.tgz cd APC-3.1.8 /usr/local/php/bin/phpize ./configure --enable-apc --enable-mmap --enable-apc-spinlocks --disable-apc-pthreadmutex --with-php-config=/usr/local/php/bin/php-config make sudo make install
第二步:配置APC
在/usr/local/php/etc/php.ini 加入如下配置項:
extension = "apc.so" ; ;APC setting apc.enabled = 1 apc.shm_segments = 1 apc.shm_size = 64M apc.optimization = 1 apc.num_files_hint = 0 apc.ttl = 0 apc.gc_ttl = 3600 apc.cache_by_default = on
第三步:檢查安裝是否成功
重啓apache 或者 /usr/local/php/sbin/php-fpm restart
查看phpinfo中是否有apc相關項
3、配置參數詳解和使用總結
1).APC模塊的參數配置詳解
apc.enabled 布爾型
apc.enabled 能夠被設成 0 來禁用 APC。這主要是有用的,當 APC 被靜態編譯入 PHP 時,由於沒有其它方法來禁用它(當編譯爲 DSO 的時候,能夠將 php.ini 中的 extension 行註釋掉)。
apc.shm_segments 整型
對編譯緩存分配共享內存塊的數量。若是APC用光了共享內存,並且你已經設置apc.shm_size爲系統容許的最大值的狀況下,你能夠試着去提升這個參數的值。
apc.shm_size 整型
每一個共享內存塊的大小是以MB爲單位的。在默認狀況下,一些系統(包括大多數BSD變種系統)的共享內存塊的大小限制的很低。
apc.optimization 整型
優化等級。設爲0則禁用優化,越高的值使用越強有力的優化。期待有適度的速度上的改進。這個仍是實驗性質的。
apc.num_files_hint 整型
對在你的Web服務器上被包含和請求的不一樣的源文件的數量的提示。若是你沒法肯定,設置爲0或者省略;這個設置主要可能用於有成千的源文件的站點。
apc.ttl 整型
當一個緩存條目在緩存區的位置被另外一個條目須要時,咱們須要考慮的是這個緩存條目在緩存區的位置被容許空閒的秒數。將這個參數設置爲0意味着你的緩存可能充滿不新鮮的條目,同時致使新的條目沒法被緩存。
apc.gc_ttl 整型
緩存條目在垃圾收集列表中存活的秒數。這個值提供了出錯保護在執行一個緩存源文件,而同時服務器進程死了的事件中。若是那個源文件被修改,內存分配給舊版本的緩存條目將不會被回收,直到這個參數設定的TTL值到的時候。設置爲0就是禁止這個特性。
apc.cache_by_default 布爾型
默認爲On,但能夠被設置爲Off並和以加號開頭的apc.filters配合使用,文件僅僅在匹配過濾器時才被緩存。
apc.filters 字符串
一個以逗號分割的POSIX擴展正則表達式的列表。若是任何模式匹配源文件名,這個文件將不會被緩存。注意用來匹配的文件名是傳遞給 include/require 的文件名,而不是絕對路徑。若是正則表達式的第一個字符是 + ,則這個表達式就意味着任何匹配表達式的文件將會被緩存,若是第一個字符是 - 則任何匹配都不會被緩存。 - 是默認值,因此能夠被省略。
apc.mmap_file_mask 字符串 (這段實在不太懂,因此沒有翻譯)
If compiled with MMAP support by using --enable-mmap this is the mktemp-style file_mask to pass to the mmap module for determing whether your mmap'ed memory region is going to be file-backed or shared memory backed. For straight file-backed mmap, set it to something like/tmp/apc.XXXXXX (exactly 6 Xs). To use POSIX-style shm_open/mmap put a .shm somewhere in your mask. e.g. /apc.shm.XXXXXX You can also set it to /dev/zero to use your kernel's/dev/zero interface to anonymous mmap'ed memory. Leaving it undefined will force an anonymous mmap.
apc.slam_defense 整型
在很是繁忙的服務器上,不管你啓動服務仍是修改文件,你都會致使一種多進程都試圖在同一個時間緩存同一個文件的競爭。這個選項設置了進程跳過試圖去緩存一個未被緩存的文件的百分比。或者能夠把這個想象成一個單獨進程跳過緩存的機率。例如,設置apc.slam_defense爲75就意味着進程有75%的機率不去緩存未被緩存的文件。因此,設置的越高,越能減小緩存的碰撞機率。設置爲0則禁用這個特性。
apc.file_update_protection 整型
當你在一個運行着的服務器上修改文件時,你應該執行原子操做。也就是,先寫一個臨時文件,當寫完後再重命名(mv)這個文件到它的最終位置。許多文本編輯器,cp,tar和其餘一些相似程序都不是這樣操做的。這就意味着有機會去訪問和(緩存)文件,當這個文件還在被寫的狀況下。apc.file_update_protection的設置使得緩存標記新文件的延遲。默認值是2,意味着若是發現文件的修改時間距離訪問時間不到2秒,文件將不會被緩存。訪問寫到一半的文件的不幸用戶將會看到離奇的狀況,但至少這種狀況不是持續的。若是你確信你常用原子操做來更新你的文件,你能夠關閉這個保護經過設置這個參數爲0。若是你的系統充滿io操做,並致使更新程序花費超過2秒,你可能須要去增大這個值。
apc.enable-cli 整型
大可能是爲了測試和調試。
爲CLI版本的PHP開啓動APC功能。通常來講,將不會想到爲每個CLI請求建立,移植和放棄APC的緩存,但對於各類測試狀況,這是很容易的爲了CLI版本開啓APC。
2).使用總結
1,使用Spinlocks鎖機制,可以達到最佳性能。
2,APC提供了apc.php,用於監控與管理APC緩存。不要忘記修改管理員名和密碼
3,APC默認經過mmap匿名映射建立共享內存,緩存對象都存放在這塊」大型」的內存空間。由APC自行管理該共享內存
4,咱們須要經過統計調整apc.shm_size、apc.num_files_hints、apc.user_entries_hint的值。直到最佳
5,好吧,我認可apc.stat = 0 能夠得到更佳的性能。要我作什麼均可以接受.
6,PHP預約義常量,可使用apc_define_constants()函數。不過據APC開發者介紹說pecl hidef性能更佳,拋異define吧,它是低效的。
7,函數apc_store(),對於系統設置等PHP變量,生命週期是整個應用(從httpd守護進程直到httpd守護進程關閉),使用APC比Memcached會更好。必竟不要通過網絡傳輸協議tcp。
8,APC不適於經過函數apc_store()緩存頻繁變動的用戶數據,會出現一些奇異現象。
4、使用實例
引用initphp框架的APC緩存類
<?php if class Apc{ /** * Apc緩存-設置緩存 * 設置緩存key,value和緩存時間 * @param string $key KEY值 * @param string $value 值 * @param string $time 緩存時間 */ 腳本學堂 http://www.jbxue.com public function set_cache($key, $value, $time = 0) { if ($time == 0) $time = null; //null狀況下永久緩存 return apc_store($key, $value, $time);; } /** * Apc緩存-獲取緩存 * 經過KEY獲取緩存數據 * @param string $key KEY值 */ public function get_cache($key) { return apc_fetch($key); } /** * Apc緩存-清除一個緩存 * 從memcache中刪除一條緩存 * @param string $key KEY值 */ public function clear($key) { return apc_delete($key); } /** * Apc緩存-清空全部緩存 * 不建議使用該功能 * @return */ public function clear_all() { apc_clear_cache('user'); //清除用戶緩存 return apc_clear_cache(); //清楚緩存 } /** * 檢查APC緩存是否存在 * @param string $key KEY值 */ public function exists($key) { return apc_exists($key); } /** * 字段自增-用於記數 * @param string $key KEY值 * @param int $step 新增的step值 */ public function inc($key, $step) { return apc_inc($key, (int) $step); } /** * 字段自減-用於記數 * @param string $key KEY值 * @param int $step 新增的step值 */ public function dec($key, $step) { return apc_dec($key, (int) $step); } /** * 返回APC緩存信息 */ public function info() { return apc_cache_info(); } }