緩存捡絮,顧名思義臼闻,就是臨時存儲信息以提高訪問性能琅束。PHP的緩存技術大體可分為三大類:
1. 緩存內(nèi)容(Caching content)
2. 內(nèi)存緩存(Memory Cache)
3. 數(shù)據(jù)庫緩存(Database Cache)
1. 緩存內(nèi)容
將某個腳本的最終輸出作為靜態(tài)文件存放在文件系統(tǒng)中搏屑,比如??信息,商品顯示頁损俭,當數(shù)據(jù)庫內(nèi)容被修改或文件過期時,重新執(zhí)行原始腳本以更新緩存內(nèi)容潘酗。簡單示例如下:
內(nèi)容緩存是最為常見的杆兵,比如輸出緩存ob_start,頁面部分緩存ob_get_contents仔夺,甚至數(shù)據(jù)庫某些查詢結(jié)果的緩存琐脏。
2. 內(nèi)存緩存
顧名思義,通過內(nèi)存進行緩存囚灼,顯然會比緩存在文件系統(tǒng)中快出許多骆膝,常見的技術如下:
Opcode Cache
簡要介紹下PHP的運行機制:a)子進程解釋器解析php腳本,比如Zend Complier; b)zend_language_scanner會首先對代碼進行掃描灶体,將PHP代碼進行詞法分析阅签,轉(zhuǎn)化為一系列的token array;c)zend_language_parse將上一步產(chǎn)生的一系列token處理空格等無用的代碼后轉(zhuǎn)化成一系列表達式蝎抽;d)這些表達式經(jīng)過complier階段生成opcode【即Operation code政钟,是一個四元組(opcode,op1,op2,result)】并返回zend_op_array指針;e)zend_vm_execute根據(jù)傳入的zend_op_array指針樟结,執(zhí)行opcode并將結(jié)果返回輸出养交;
對opcode進行緩存的軟件很多,比如apc瓢宦,eAcclerator碎连,Xcache,Zend Platform驮履,這里主要介紹下apc;
APC提供了兩種緩存功能:緩存Opcode(目標文件)鱼辙,即apc_complier_cache,緩存用戶數(shù)據(jù)即apc_user_cache. 下圖為使用了apc_complier_cache后的php解析過程:
由于apc并未內(nèi)置到PHP解釋器內(nèi)核中玫镐,你需要單獨安裝并在php.ini中添加apc配置:
apc的使用是比較簡單的倒戏,主要比較常用的有三個方法:
apc_add/apc_store–?store a variable in the cache. The only difference betweenapc_addandapc_storeis thatapc_storeoverwrites the data if it already exists andapc_adddoes not。
apc_fetch– fetch a variable from the cache
apc_delete– delete a variable from the cache.
http://www.360doc.com/content/16/0204/17/22355405_532718314.shtml
據(jù)說apc使用了spinlocks(自旋)鎖機制恐似,能夠達到最佳性能杜跷,但這也可能會死鎖,進而影響到php-fpm進程(https://yq.aliyun.com/articles/1699);
一方面apc_store對于系統(tǒng)設置等PHP變量的緩存是比較好的選擇葛闷,但apc不合適通過apc_store頻繁變更用戶數(shù)據(jù)憋槐,會出現(xiàn)一些奇異現(xiàn)象;
Memcache
分布式對象緩存系統(tǒng)孵运,通過在內(nèi)存中以鍵值對的形式緩存數(shù)據(jù)和對象以減少讀取數(shù)據(jù)庫的次數(shù)秦陋,進而提高驅(qū)動網(wǎng)站的速度飞袋。它可以應對任意多個連接妇垢,使用非阻塞的網(wǎng)絡IO。
Memcache與memcached區(qū)別:Memcache是項目名稱旅薄,而memcached是項目在服務器段的主程序文件名旷赖;
所謂的分布式對象緩存體現(xiàn)顺又,單個服務器就算了,比如現(xiàn)memcache客戶端要添加“shanghai”等孵,客戶端根據(jù)查詢算法(比如Consistent hashing)根據(jù)“鍵”來決定保存數(shù)據(jù)的memcached服務器稚照。至于memcache服務器端,它會在內(nèi)存中開辟一塊空間,然后建立一個HashTable, 并復制管理維護俯萌」迹“shanghai”到了選定的服務器后,將“shanghai”維護到HashTable咐熙,并在內(nèi)存中保存其值弱恒。
同樣在獲取保存的數(shù)據(jù)時,比如鍵值“hangzhou”棋恼,memcache客戶端會通過相同的方式返弹,根據(jù)鍵值選擇服務器,然后發(fā)送get命令取得value爪飘,當然若不幸該鍵值尚不存在或已失效义起,那就從元數(shù)據(jù)取之并reset。這樣鍵值對通過HashTable存儲到不同的服務器上师崎,就實現(xiàn)了memcached的分布式默终。
注意:查詢算法因節(jié)點分布不均而造成的數(shù)據(jù)傾斜問題,memcache服務器增多是否會影響鍵值的重新分布以及增減服務器是否會導致緩存的大范圍丟失犁罩。
Memcache區(qū)分為memcache服務器端的安裝和memcache客戶端安裝齐蔽,默認端口號11211。簡單示例如下:
既然是緩存昼汗,定是有過期時間的肴熏,比如上述圖片中set('things',$things,false,86400)鬼雀,對memcache而言顷窒,它不會在過期監(jiān)視上耗費CPU時間,當某個值過期后,其內(nèi)存并沒有被刪除鞋吉,而是當再次在get時查看記錄的時間戳鸦做,檢查記錄是否過期,如果已過期谓着,則返回空并且清空泼诱,這種技術被稱為lazy(惰性)expiration。
另外赊锚,memcache會優(yōu)先使用已超時記錄的空間治筒,但即使如此,也會發(fā)生追加新紀錄時空間不足的情況舷蒲,此時就要使用Least Recently Used(LRU)機制來分配空間【即使某個key設置的是永久有效期】耸袜。
對于分布式的對象緩存系統(tǒng)memcache,其須以root權限運行牲平,且訪問是無用戶狀態(tài)的堤框,考慮到安全性,一般通過放在內(nèi)網(wǎng)纵柿,并通過防火墻限制外網(wǎng)訪問memcache端口達到安全蜈抓。
數(shù)據(jù)庫緩存
上述的緩存技術都是在應用層討論的,database server本身也可以cache昂儒,典型的就是SQL第一次查詢時解析沟使,后續(xù)查詢則直接從database server cache中獲取結(jié)果。簡單config MySQL my.cnf如下:
query_cache_type =1
query_cache_limit = 1M
query_cache_size =16M