在WEB開發中用來應付高流量最有效的辦法就是用緩存技術,能有效的提升服務器負載性能,用空間換取時間。
緩存通常用來php
使用緩存的2個主要緣由:css
應用層緩存這塊跟開發人員關係最大,也是平時常常接觸的。html
應用層緩存的架構也能夠分幾種:前端
比較常見的應用層分佈式緩存容器,Memcache、共享文件服務器、MemcacheDb、Tokyo Tyrant。 php裏面也有好比x-cache,apc等的基於進程的緩存,這種緩存比分佈式緩存速度快,可是限於跟應用的一個機器。 java實現的緩存也比較多,好比oscache,jcache ,ehcached等等。java
咱們這裏說的前端緩存能夠理解爲通常使用的cdn技術,利用squid等作前端緩衝技術,主要仍是針對靜態文件類型,好比圖片,css,js,html等靜態文件。
通常針對靜態資源如CSS,JS,圖片等使用緩存,緣由以下:node
前端比較經常使用的就是squid,Varnish Cache,ncache等等。Varnish是一款高性能的開源HTTP加速器,挪威最大的在線報紙 Verdens Gang (vg.no) 使用3臺Varnish代替了原來的12臺squid,性能比之前更好。web
客戶端緩存依賴於瀏覽器的實現,目前通常的瀏覽器都實現了基於http都信息來緩存相應的文件。瀏覽器端的緩存,可讓用戶請求一次以後,下一次不在從服務器端請求數據,直接從本地緩存讀取,能夠減輕服務器負擔也能夠加快用戶的訪問速度。
瀏覽器緩存分爲強緩存和協商緩存:數據庫
強緩存與協商緩存區別:強緩存不發請求到服務器,協商緩存會發請求到服務器。apache
如何設置緩存
1. HTML Meta標籤控制緩存(非HTTP協議定義)
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代碼的做用是告訴瀏覽器當前頁面不被緩存,每次訪問都須要去服務器拉取。這種方法使用上很簡單,但只有部分瀏覽器能夠支持,並且全部緩存代理服務器都不支持,由於代理不解析HTML內容自己。segmentfault
2. HTTP頭信息控制緩存
HTTP頭信息發送在HTML代碼以前,只能被瀏覽器和一些中間緩存能看到,一個典型的HTTP 1.1協議返回的頭信息看上去像這樣:
HTTP/1.1 200 OK Date: Fri, 30 Oct 1998 13:19:41 GMT Server: Apache/1.3.3 (Unix) Cache-Control: max-age=3600, must-revalidate Expires: Fri, 30 Oct 1998 14:19:41 GMT Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT ETag: "3e86-410-3596fbbc" Content-Length: 1040 Content-Type: text/html
頭信息空一行後是HTML代碼的輸出。
HTTP頭信息控制緩存是經過Expires(強緩存)、Cache-control(強緩存)、Last-Modified/If-Modified-Since(協商緩存)、Etag/If-None-Match(協商緩存)實現,下面詳細介紹。
1)Expires是http1.0提出的一個表示資源過時時間的header,它描述的是一個絕對時間,由服務器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2016 23:55:55 GMT,讀取緩存數據條件:緩存過時時間(服務器的)< 當前時間(客戶端的)。
儘管Expires頭頗有用,但它有必定的侷限性。首先,由於牽扯到時間,Web服務器端的時鐘必須和緩存的同步,不然極可能實現不了預期的結果——緩存把前女朋友當初現女朋友,把現女朋友看成過去式——那就悲劇了。另一個問題是,你很容易忘記給某內容設置了一個特定時間,若是返回內容的時候沒有更新這個過時時間,則每一個請求都是上訪到服務器,反而增長了負載和響應時間。
缺點:Expires是較老的強緩存管理header,因爲它是服務器返回的一個絕對時間,這樣存在一個問題,若是客戶端的時間與服務器的時間相差很大(好比時鐘不一樣步,或者跨時區),那麼偏差就很大,因此在HTTP 1.1版開始,使用Cache-Control: max-age=秒替代。
2)Cache-Control(緩存控制)HTTP頭信息,是HTTP 1.1引入了新的頭信息,描述的是一個相對時間,在進行緩存命中的時候,都是利用客戶端時間進行判斷,因此相比較Expires,Cache-Control的緩存管理更有效,安全一些。讀取緩存數據條件:上次緩存時間(客戶端的)+max-age < 當前時間(客戶端的)。Cache-Control值能夠是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age
各個消息中的指令含義以下:
注意:這兩個header能夠只啓用一個,也能夠同時啓用,當response header中,Expires和Cache-Control同時存在時,Cache-Control優先級高於Expires。
3)Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:標示這個響應資源的最後修改時間。web服務器在響應請求時,告訴瀏覽器資源的最後修改時間。
If-Modified-Since:當資源過時時(強緩存失效),發現資源具備Last-Modified聲明,則再次向web服務器請求時帶上頭 If-Modified-Since,表示請求時間。web服務器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對。若最後修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最後修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。
缺點:Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間(沒法及時更新文件)
若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存,有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形(沒法使用緩存)。
HTTP1.1中Etag解決了上述問題。
4)Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器的惟一標識(生成規則由服務器決定)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後獲得的。
If-None-Match:當資源過時時(使用Cache-Control標識的max-age),發現資源具備Etage聲明,則再次向web服務器請求時帶上頭If-None-Match (Etag的值)。web服務器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified與ETag一塊兒使用時,服務器會優先驗證ETag。
yahoo的Yslow法則中則提示謹慎設置Etag:須要注意的是分佈式系統裏多臺機器間文件的last-modified必須保持一致,以避免負載均衡到不一樣機器致使比對失敗,Yahoo建議分佈式系統儘可能關閉掉Etag(每臺機器生成的etag都會不同,由於除了 last-modified、inode 也很難保持一致)。
咱們這幾隻講應用層的緩存。在應用層的緩存因爲應經有新的數據加入,數據的修改,數據的刪除等等操做,而在某些時間,咱們須要這些操做及時的生效(因爲用了緩存,可能會致使修改後緩存沒有更新,而頁面也沒有變化),因此出現緩存的更新和過時的概念。
緩存的過時包含
緩存的更新
速度:固然,咱們使用緩存的目的之一就是要提升咱們應用的速度。若是使用緩存後速度更慢那就沒有緩存的必要了。取緩存的速度應 當是很是快的,由於緩存的工做僅僅是取出一個曾經存儲好的數據。因此影響緩存速度的因素可能跟緩存所才採用的存儲方式有關係,還有可能印象速度的就是分佈 式緩存的網絡消耗,一樣,緩存服務器在併發很大的時候也有可能不堪重負出現瓶頸,變得緩慢。
好比目前鳳凰論壇使用的帖子緩存的響應時間在亞毫秒級,也就是還不足1ms的響應時間,這個速度是至關快的。
及時性:咱們使用緩存的重要一點就是對咱們的數據的更新須要緩存也及時的更新。這點很是重要,關係到頁面顯示的正確性,用戶體驗等。
命中率:命中率直接關係到緩存所起到的做用的大小。若是命中率過低就至關於沒有使用緩存,或者咱們的緩存的規則有問題,重視命中不到緩存。
哪些地方須要緩存
選擇什麼緩存
緩存如此有用,那麼這麼多的緩存產品,咱們如何選擇呢?下面咱們主要就經常使用的php方面來講。
其實這裏也可使用共享的磁盤緩存,可是基於咱們目前所處的環境和對於可靠性,高併發的要求,咱們不建議或者說不考慮使用共享磁盤做爲緩存。
一、全頁面靜態化緩存
也就是將頁面所有生成html靜態頁面,用戶訪問時直接訪問的靜態頁面,而不會去走php服務器解析的流程。此種方式,在CMS系統中比較常見,好比dedecms;
二、頁面部分緩存
該種方式,是將一個頁面中不常常變的部分進行靜態緩存,而常常變化的塊不緩存,最後組裝在一塊兒顯示;可使用相似於ob_get_contents的方式實現,也能夠利用相似ESI之類的頁面片斷緩存策略,使其用來作動態頁面中相對靜態的片斷部分的緩存(ESI技術,請baidu,此處不詳講)。該種方式能夠用於如商城中的商品頁。
三、數據緩存
顧名思義,就是緩存數據的一種方式;好比,商城中的某個商品信息,當用商品id去請求時,就會得出包括店鋪信息、商品信息等數據,此時就能夠將這些數據緩存到一個php文件中,文件名包含商品id來建一個惟一標示;下一次有人想查看這個商品時,首先就直接調這個文件裏面的信息,而不用再去數據庫查詢;其實緩存文件中緩存的就是一個php數組之類。Ecmall商城系統裏面就用了這種方式。
四、查詢緩存
其實這跟數據緩存是一個思路,就是根據查詢語句來緩存;將查詢獲得的數據緩存在一個文件中,下次遇到相同的查詢時,就直接先從這個文件裏面調數據,不會再去查數據庫;但此處的緩存文件名可能就須要以查詢語句爲基點來創建惟一標示;
按時間變動進行緩存:其實,這一條不是真正的緩存方式;上面的二、三、4的緩存技術通常都用到了時間變動判斷;就是對於緩存文件您須要設一個有效時間,在這個有效時間內,相同的訪問纔會先取緩存文件的內容,可是超過設定的緩存時間,就須要從新從數據庫中獲取數據,並生產最新的緩存文件;好比,我將咱們商城的首頁就是設置2個小時更新一次。
五、按內容變動進行緩存
這個也並不是獨立的緩存技術,需結合着用;就是當數據庫內容被修改時,即刻更新緩存文件。好比,一我的流量很大的商城,商品不少,商品表必然比較大,這表的壓力也比較重;咱們就能夠對商品顯示頁進行頁面緩存;當商家在後臺修改這個商品的信息時,點擊保存,咱們同時就更新緩存文件;那麼,買家訪問這個商品信息時,實際上訪問的是一個靜態頁面,而不須要再去訪問數據庫。
試想,若是對商品頁不緩存,那麼每次訪問一個商品就要去數據庫查一次,若是有10萬人在線瀏覽商品,那服務器壓力就大了;
六、內存式緩存
提到這個,可能你們想到的首先就是Memcached;memcached是高性能的分佈式內存緩存服務器。 通常的使用目的是,經過緩存數據庫查詢結果,減小數據庫訪問次數,以提升動態Web應用的速度、 提升可擴展性。它就是將須要緩存的信息,緩存到系統內存中,須要獲取信息時,直接到內存中取;比較經常使用的方式就是 key–>value方式。
七、apache緩存模塊
apache安裝完之後,是不容許被cache的。若是外接了cache或squid服務器要求進行web加速的話,就須要在htttpd.conf裏進行設置,固然前提是在安裝apache的時候要激活mod_cache的模塊。
安裝apache時:./configure –enable-cache –enable-disk-cache –enable-mem-cache
八、php APC緩存擴展
Php有一個APC緩存擴展,windows下面爲php_apc.dll,須要先加載這個模塊,而後是在php.ini裏面進行配置:
[apc] extension=php_apc.dll apc.rfc1867 = on upload_max_filesize = 100M post_max_size = 100M apc.max_file_size = 200M upload_max_filesize = 1000M post_max_size = 1000M max_execution_time = 600 ; 每一個PHP頁面運行的最大時間值(秒),默認30秒 max_input_time = 600 ; 每一個PHP頁面接收數據所需的最大時間,默認60 memory_limit = 128M ; 每一個PHP頁面所吃掉的最大內存,默認8M
九、Opcode緩存
PHP的緩衝器、加速器,有eaccelerator, apc, phpa,xcache。
首先php代碼被解析爲Tokens,而後再編譯爲Opcode碼,最後執行Opcode碼,返回結果;因此,對於相同的php文件,第一次運行時能夠緩存其Opcode碼,下次再執行這個頁面時,直接會去找到緩存下的opcode碼,直接執行最後一步,而再也不須要中間的步驟了。比較知名的是XCache、Turck MM Cache、PHP Accelerator等。
http://www.cnblogs.com/sunli/archive/2009/11/24/1609444.html
https://segmentfault.com/a/1190000006741200
https://my.oschina.net/leejun2005/blog/369148
http://www.oschina.net/news/41397/web-cache-knowledge
http://www.open-open.com/lib/view/open1479181086120.html
http://www.jb51.net/article/49714.htm
http://www.php100.com/html/php/lei/2015/0919/8969.html
版權聲明:本文采用署名-非商業性使用-相同方式共享(CC BY-NC-SA 3.0 CN)國際許可協議進行許可,轉載請註明做者及出處。 |