|
一、APC緩存簡(jiǎn)介
APC,全稱是Alternative php Cache,官方翻譯叫”可選php緩存”。它為我們提供了緩存和優(yōu)化php的中間代碼的框架。 APC的緩存分兩部分:系統(tǒng)緩存和用戶數(shù)據(jù)緩存。
系統(tǒng)緩存
它是指APC把php文件源碼的編譯結(jié)果緩存起來(lái),然后在每次調(diào)用時(shí)先對(duì)比時(shí)間標(biāo)記。如果未過(guò)期,則使用緩存的中間代碼運(yùn)行。默認(rèn)緩存
3600s(一小時(shí))。但是這樣仍會(huì)浪費(fèi)大量CPU時(shí)間。因此可以在php.ini中設(shè)置system緩存為永不過(guò)期(apc.ttl=0)。不過(guò)如果這樣設(shè)置,改運(yùn)php代碼后需要重啟WEB服務(wù)器。目前使用較多的是指此類緩存。
用戶數(shù)據(jù)緩存
緩存由用戶在編寫(xiě)php代碼時(shí)用apc_store和apc_fetch函數(shù)操作讀取、寫(xiě)入的。如果數(shù)據(jù)量不大的話,可以一試。如果數(shù)據(jù)量大,使用類似memcache此類的更加專著的內(nèi)存緩存方案會(huì)更好
緩存key生成規(guī)則
APC的緩存中的每個(gè)slot都會(huì)有一個(gè)key,key是
apc_cache_key_t結(jié)構(gòu)體類型,除了key相關(guān)的屬性,關(guān)鍵是h字段的生成。 h字段決定了此元素落于slots數(shù)組的哪一個(gè)位置。對(duì)于用戶緩存和系統(tǒng)緩存,其生成規(guī)則不同。 用戶緩存通過(guò)apc_cache_make_user_key函數(shù)生成key。通過(guò)用戶傳遞進(jìn)來(lái)的key字符串,依賴php內(nèi)核中的hash函數(shù)(php的hashtable所使用的hash函數(shù):zend_inline_hash_func),生成h值。
系統(tǒng)緩存通過(guò)apc_cache_make_file_key函數(shù)生成key。通過(guò)APC的配置項(xiàng)apc.stat的開(kāi)關(guān)來(lái)區(qū)別對(duì)待不同的方案。在打開(kāi)的情況下,即
apc.stat= On 時(shí),如果被更新則自動(dòng)重新編譯和緩存編譯后的內(nèi)容。此時(shí)的h值是文件的device和inode相加所得的值。在關(guān)閉的情況下,即apc.stat=off時(shí),當(dāng)文件被修改后,如果要使更新的內(nèi)容生效,則必須重啟Web服務(wù)器。此時(shí)h值是根據(jù)文件的路徑地址生成,并且這里的路徑是絕對(duì)路徑。即使你是使用的相對(duì)路徑,也會(huì)查找PG(include_path)定位文件,以取得絕對(duì)路徑,所以使用絕對(duì)路徑會(huì)跳過(guò)檢查,可以提高代碼的效率。
添加緩存過(guò)程
以用戶緩存為例,apc_add函數(shù)用于給APC緩存中添加內(nèi)容。如果key參數(shù)為字符串中,APC會(huì)根據(jù)此字符串生成key,如果key參數(shù)為數(shù)組,APC會(huì)遍歷整個(gè)數(shù)組,生成key。根據(jù)這些key,APC會(huì)調(diào)用_apc_store將值存儲(chǔ)到緩存中。由于這是用戶緩存,當(dāng)前使用的緩存為apc_user_cache。執(zhí)行寫(xiě)入操作的是apc_cache_make_user_entry函數(shù),其最終調(diào)用apc_cache_user_insert執(zhí)行遍歷查詢和寫(xiě)入操作。與此對(duì)應(yīng),系統(tǒng)緩存使用apc_cache_insert執(zhí)行寫(xiě)入操作,其最終都會(huì)調(diào)用_apc_cache_insert。
不管是用戶緩存還是系統(tǒng)緩存,大體的執(zhí)行過(guò)程類似,步驟如下:
通過(guò)求余操作,定位當(dāng)前key的在slots數(shù)組中的位置: cache->slots[key.h % cache->num_slots];
在定位到slots數(shù)組中的位置后,遍歷當(dāng)前key對(duì)應(yīng)的slot鏈表,如果存在slot的key和要寫(xiě)入的key匹配或slot過(guò)期,清除當(dāng)前slot。
在最后一個(gè)slot的后面插入新的slot。
二、APC模塊安裝
A.WINDOWS下安裝APC
第一步:下載php_apc.dll 在http://pecl.php.NET/package/apc 要與php版本對(duì)應(yīng) 將php_apc.dll放入你的ext目錄
第二步:讓php.ini支持apc擴(kuò)展模塊。 然后打開(kāi)php.ini 加入:
復(fù)制代碼 代碼如下:extension=php_apc.dll
apc.rfc1867 = on
apc.max_file_size = 100M
upload_max_filesize = 100M
post_max_size = 100M
//以上參數(shù)可自己定義
第三步:檢查是否支持php APC apc_store apc_fetch
查看phpinfo中是否有apc相關(guān)項(xiàng)
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 加入以下配置項(xiàng):
復(fù)制代碼 代碼如下:
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相關(guān)項(xiàng)
三、配置參數(shù)詳解和使用總結(jié)
1).APC模塊的參數(shù)配置詳解
復(fù)制代碼 代碼如下:
apc.enabled 布爾型
apc.enabled 可以被設(shè)成 0 來(lái)禁用 APC。這主要是有用的,當(dāng) APC 被靜態(tài)編譯入 php 時(shí),因?yàn)闆](méi)有其它方法來(lái)禁用它(當(dāng)編譯為 DSO 的時(shí)候,可以將 php.ini 中的 extension 行注釋掉)。
apc.shm_segments 整型
對(duì)編譯緩存分配共享內(nèi)存塊的數(shù)量。如果APC用光了共享內(nèi)存,而且你已經(jīng)設(shè)置apc.shm_size為系統(tǒng)允許的最大值的情況下,你可以試著去提高這個(gè)參數(shù)的值。
apc.shm_size 整型
每個(gè)共享內(nèi)存塊的大小是以MB為單位的。在默認(rèn)情況下,一些系統(tǒng)(包括大多數(shù)BSD變種系統(tǒng))的共享內(nèi)存塊的大小限制的很低。
apc.optimization 整型
優(yōu)化等級(jí)。設(shè)為0則禁用優(yōu)化,越高的值使用越強(qiáng)有力的優(yōu)化。期待有適度的速度上的改進(jìn)。這個(gè)還是實(shí)驗(yàn)性質(zhì)的。
apc.num_files_hint 整型
對(duì)在你的Web服務(wù)器上被包含和請(qǐng)求的不同的源文件的數(shù)量的提示。如果你無(wú)法確定,設(shè)置為0或者省略;這個(gè)設(shè)置主要可能用于有成千的源文件的站點(diǎn)。
apc.ttl 整型
當(dāng)一個(gè)緩存條目在緩存區(qū)的位置被另一個(gè)條目需要時(shí),我們需要考慮的是這個(gè)緩存條目在緩存區(qū)的位置被允許空閑的秒數(shù)。將這個(gè)參數(shù)設(shè)置為0意味著你的緩存可能充滿不新鮮的條目,同時(shí)導(dǎo)致新的條目無(wú)法被緩存。
apc.gc_ttl 整型
緩存條目在垃圾收集列表中存活的秒數(shù)。這個(gè)值提供了出錯(cuò)保護(hù)在執(zhí)行一個(gè)緩存源文件,而同時(shí)服務(wù)器進(jìn)程死了的事件中。如果那個(gè)源文件被修改,內(nèi)存分配給舊版本的緩存條目將不會(huì)被回收,直到這個(gè)參數(shù)設(shè)定的TTL值到的時(shí)候。設(shè)置為0就是禁止這個(gè)特性。
apc.cache_by_default 布爾型
默認(rèn)為On,但可以被設(shè)置為Off并和以加號(hào)開(kāi)頭的apc.filters配合使用,文件僅僅在匹配過(guò)濾器時(shí)才被緩存。
apc.filters 字符串
一個(gè)以逗號(hào)分割的POSIX擴(kuò)展正則表達(dá)式的列表。如果任何模式匹配源文件名,這個(gè)文件將不會(huì)被緩存。注意用來(lái)匹配的文件名是傳遞給 include/require 的文件名,而不是絕對(duì)路徑。如果正則表達(dá)式的第一個(gè)字符是 + ,則這個(gè)表達(dá)式就意味著任何匹配表達(dá)式的文件將會(huì)被緩存,如果第一個(gè)字符是 - 則任何匹配都不會(huì)被緩存。 - 是默認(rèn)值,所以可以被省略。
apc.mmap_file_mask 字符串 (這段實(shí)在不太懂,所以沒(méi)有翻譯)
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 整型
在非常繁忙的服務(wù)器上,無(wú)論你啟動(dòng)服務(wù)還是修改文件,你都會(huì)導(dǎo)致一種多進(jìn)程都試圖在同一個(gè)時(shí)間緩存同一個(gè)文件的競(jìng)爭(zhēng)。這個(gè)選項(xiàng)設(shè)置了進(jìn)程跳過(guò)試圖去緩存一個(gè)未被緩存的文件的百分比。或者可以把這個(gè)想象成一個(gè)單獨(dú)進(jìn)程跳過(guò)緩存的機(jī)率。例如,設(shè)置apc.slam_defense為75就意味著進(jìn)程有75%的機(jī)率不去緩存未被緩存的文件。所以,設(shè)置的越高,越能減少緩存的碰撞機(jī)率。設(shè)置為0則禁用這個(gè)特性。
apc.file_update_protection 整型
當(dāng)你在一個(gè)運(yùn)行著的服務(wù)器上修改文件時(shí),你應(yīng)該執(zhí)行原子操作。也就是,先寫(xiě)一個(gè)臨時(shí)文件,當(dāng)寫(xiě)完后再重命名(mv)這個(gè)文件到它的最終位置。許多文本編輯器,cp,tar和其他一些類似程序都不是這樣操作的。這就意味著有機(jī)會(huì)去訪問(wèn)和(緩存)文件,當(dāng)這個(gè)文件還在被寫(xiě)的情況下。apc.file_update_protection的設(shè)置使得緩存標(biāo)記新文件的延遲。默認(rèn)值是2,意味著如果發(fā)現(xiàn)文件的修改時(shí)間距離訪問(wèn)時(shí)間不到2秒,文件將不會(huì)被緩存。訪問(wèn)寫(xiě)到一半的文件的不幸用戶將會(huì)看到離奇的情況,但至少這種情況不是持續(xù)的。如果你確信你經(jīng)常使用原子操作來(lái)更新你的文件,你可以關(guān)閉這個(gè)保護(hù)通過(guò)設(shè)置這個(gè)參數(shù)為0。如果你的系統(tǒng)充滿io操作,并導(dǎo)致更新程序花費(fèi)超過(guò)2秒,你可能需要去增大這個(gè)值。
apc.enable-cli 整型
大多是為了測(cè)試和調(diào)試。為CLI版本的php開(kāi)啟動(dòng)APC功能。一般來(lái)說(shuō),你將不會(huì)想到為每一個(gè)CLI請(qǐng)求創(chuàng)建,移植和放棄APC的緩存,但對(duì)于各種測(cè)試情況,這是很容易的為了CLI版本開(kāi)啟APC。
2).使用總結(jié)
1,使用Spinlocks鎖機(jī)制,能夠達(dá)到最佳性能。
2,APC提供了apc.php,用于監(jiān)控與管理APC緩存。不要忘記修改管理員名和密碼
3,APC默認(rèn)通過(guò)mmap匿名映射創(chuàng)建共享內(nèi)存,緩存對(duì)象都存放在這塊”大型”的內(nèi)存空間。由APC自行管理該共享內(nèi)存
4,我們需要通過(guò)統(tǒng)計(jì)調(diào)整apc.shm_size、apc.num_files_hints、apc.user_entries_hint的值。直到最佳
5,好吧,我承認(rèn)apc.stat = 0 可以獲得更佳的性能。要我做什么都可以接受.
6,php預(yù)定義常量,可以使用apc_define_constants()函數(shù)。不過(guò)據(jù)APC開(kāi)發(fā)者介紹說(shuō)pecl hidef性能更佳,拋異define吧,它是低效的。
7,函數(shù)apc_store(),對(duì)于系統(tǒng)設(shè)置等php變量,生命周期是整個(gè)應(yīng)用(從httpd守護(hù)進(jìn)程直到httpd守護(hù)進(jìn)程關(guān)閉),使用APC比Memcached會(huì)更好。必竟不要經(jīng)過(guò)網(wǎng)絡(luò)傳輸協(xié)議tcp。
8,APC不適于通過(guò)函數(shù)apc_store()緩存頻繁變更的用戶數(shù)據(jù),會(huì)出現(xiàn)一些奇異現(xiàn)象。
四、使用實(shí)例
下面引用initphp框架的APC緩存類
復(fù)制代碼 代碼如下:
<?php
if
class Apc{
/**
* Apc緩存-設(shè)置緩存
* 設(shè)置緩存key,value和緩存時(shí)間
* @param string $key KEY值
* @param string $value 值
* @param string $time 緩存時(shí)間
*/
public function set_cache($key, $value, $time = 0) {
if ($time == 0) $time = null; //null情況下永久緩存
return apc_store($key, $value, $time);;
}
/**
* Apc緩存-獲取緩存
* 通過(guò)KEY獲取緩存數(shù)據(jù)
* @param string $key KEY值
*/
public function get_cache($key) {
return apc_fetch($key);
}
/**
* Apc緩存-清除一個(gè)緩存
* 從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);
}
/**
* 字段自增-用于記數(shù)
* @param string $key KEY值
* @param int $step 新增的step值
*/
public function inc($key, $step) {
return apc_inc($key, (int) $step);
}
/**
* 字段自減-用于記數(shù)
* @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();
}
}
php技術(shù):PHP APC緩存配置、使用詳解,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。