緩存是什么
1)許多人認為熔任,“緩存”是內存的一部分褒链。許多技術文章都是這樣教授的,但是還是有很多人不知道緩存在什么地方疑苔,緩存是做什么用的甫匹?其實,緩存是CPU的一部分惦费,它存在于CPU中兵迅。
2)CPU存取數據的速度非常的快,一秒鐘能夠存取薪贫、處理十億條指令和數據恍箭。而內存就慢很多,快的內存能夠達到幾十兆就不錯了瞧省,可見兩者的速度差異是多么的大扯夭。
3)CPU高速緩存的出現(xiàn)主要是為了解決CPU運算速度與內存讀寫速度不匹配的矛盾,因為CPU運算速度要比內存讀寫速度快很多鞍匾,這樣會使CPU花費很長時間等待數據到來或把數據寫入內存交洗。在緩存中的數據是內存中的一小部分,但這一小部分是短時間內CPU即將訪問的橡淑,當CPU調用大量數據時构拳,就可先緩存中調用,從而加快讀取速度梁棠。
4)當CPU需要讀取數據并進行計算時置森,首先需要將CPU緩存中查到所需的數據,并在最短的時間下交付給CPU符糊。如果沒有查到所需的數據凫海,CPU就會提出“要求”經過緩存從內存中讀取,再原路返回至CPU進行計算男娄。而同時盐碱,把這個數據所在的數據也調入緩存,可以使得以后對整塊數據的讀取都從緩存中進行沪伙,不必再調用內存。
緩存在不同場景的分類
客戶端緩存
瀏覽器的緩存可以將之前渲染的頁面保存為文件县好,當用戶再次訪問時可以避開網絡連接围橡,從而減少負載。如何把客戶端緩存對于業(yè)務組件透明和客戶端緩存數據及時更新缕贡,是客戶端緩存能否成功應用的關鍵翁授〖鸩ィ客戶端可以將內同緩存在內存、文件或本地數據庫中收擦。
網頁瀏覽器啟用緩存策略后贮配,訪問靜態(tài)圖片文件時客戶端與服務器交互如下:
If-Modified-Since是標準的HTTP請求頭標簽,在發(fā)送HTTP請求時塞赂,把瀏覽器端緩存頁面的最后修改時間一起發(fā)到服務器去泪勒,服務器會把這個時間與服務器上實際文件的最后修改時間進行比較。如果時間一致宴猾,那么返回HTTP狀態(tài)碼304(不返回文件內容)圆存,客戶端接到之后,就直接把本地緩存文件顯示到瀏覽器中仇哆;如果時間不一致沦辙,就返回HTTP狀態(tài)碼200和新的文件內容,客戶端接到之后讹剔,會丟棄舊文件油讯,把新文件緩存起來,并顯示到瀏覽器中延欠。
web代理
web代理的作用跟瀏覽器的內置緩存類似陌兑,位于瀏覽器和互聯(lián)網之間,網絡請求通過代理來中繼衫冻。對于企業(yè)而言诀紊,既可以節(jié)省成本,又能提高性能隅俘。
常用的web代理有Varnish邻奠,Ngnix,Squid为居,它們都是反向代理 碌宴。反向代理一般緩存靜態(tài)資源,動態(tài)資源轉發(fā)到應用服務器處理蒙畴。以Squid為例贰镣,Squid反向代理一般只緩存靜態(tài)資源,動態(tài)程序默認不緩存膳凝。根據從WEB服務器返回的HTTP頭標記來緩沖靜態(tài)頁面碑隆。有四個最重要HTTP 頭標記:
- Last-Modified: 告訴反向代理頁面什么時間被修改
- Expires: 告訴反向代理頁面什么時間應該從緩沖區(qū)中刪除
- Cache-Control: 告訴反向代理頁面是否應該被緩沖
- Pragma: 用來包含實現(xiàn)特定的指令,最常用的是Pragma:no-cache
Squid 反向代理加速網站實例:
- 通過DNS的輪詢技術蹬音,將客戶端的請求分發(fā)給其中一臺Squid 反向代理服務器處理上煤;
- 如果這臺 Squid 緩存了用戶的請求資源,則將請求的資源直接返回給用戶著淆;
- 否則這臺 Squid 將沒有緩存的請求根據配置的規(guī)則發(fā)送給鄰居Squid 和后臺的WEB 服務器處理劫狠;
- 這樣既減輕后臺 WEB 服務器的負載拴疤,又提高整個網站的性能和安全性。
邊緣緩存
邊緣緩存位于應用服務器的前面独泞,可以處理來自不同用戶的請求呐矾,主要用于向用戶提供靜態(tài)的內容,以減少應用服務器的接入懦砂。邊緣緩存的商業(yè)化服務就是CDN了蜒犯。
CDN的全稱是Content Delivery Network,即內容分發(fā)網絡孕惜。CDN將網站的內容發(fā)布到最接近用戶的網絡 " 邊緣 " 愧薛,使用戶可以就近取得所需的內容,降低網絡擁塞衫画,提高用戶訪問響應速度和命中率毫炉。
CDN本質就是加速用戶獲取資源的系統(tǒng)。這些資源可以是靜態(tài)資源削罩,也可以是動態(tài)資源瞄勾,取決于我們的推送策略。不過還是建議使用CDN加速網站的靜態(tài)部分∶旨ぃ現(xiàn)在大部分的視頻加速完全取決于CDN进陡。視頻資源都是放到CDN上,用來加速用戶獲取數據的速度微服,用戶一般通過運營商趾疚,比如接入電信、長城這些運營商以蕴。用戶想上網的時候通過這些運營商的接口糙麦,去訪問離它最近的城域網的地址,再通過城域網跳到主干網丛肮,主干網再通過IP來找到對應的訪問資源所在的服務器赡磅。當然很大一部分內容已經在上層的節(jié)點上CDN已經找到了對應的內容,他也就不用再往后查找直接返回對應的資源宝与。
CDN和反向代理的基本原理都是緩存焚廊,區(qū)別在于CDN部署在網絡提供商的機房,使用戶在請求網站服務時习劫,可以從距離自己最近的網絡提供商機房獲取數據咆瘟;而反向代理則部署在應用服務器機房,當用戶請求到達中心機房后诽里,首先訪問的服務器反向代理服務器搞疗,如果反向代理服務器中緩存著用戶請求的資源,就將其直接返回給用戶。
CDN=更智能的鏡像+緩存+流量導流匿乃。鏡像指的是把網站上的靜態(tài)內容下載到各地服務器上。
平臺緩存
平臺緩存是用來寫應用的框架豌汇,或者緩存的專用庫幢炸。Java語言中,緩存框架很多拒贱,例如EHcache宛徊、JBoss Cache等等。簡單來說逻澳,就平臺級緩存而言闸天,只需要在框架側配置一下屬性即可,不需要調用特定的方法或函數斜做。
應用緩存
應用及緩存苞氮,需要自己通過代碼來實現(xiàn)緩存。這里是NoSQL的勝場瓤逼,不論是Redis還是MongoDB笼吟,都可以作為應用緩存的工具。一個典型的方式是霸旗,每分鐘或一段時間后統(tǒng)一生成某類頁面存儲在緩存中贷帮,也可以在熱數據變化時更新緩存。
數據庫緩存
數據庫緩存是一類特殊的緩存诱告。大多數數據庫不需要配置就可以快速運行撵枢,但并沒有為特定的需求進行優(yōu)化。在數據庫調優(yōu)的時候精居,緩存優(yōu)化是一項很重要的工作锄禽。
MySQL為例,MySQL中使用了查詢緩沖機制箱蟆,將Select語句和查詢結果存放在緩沖區(qū)中沟绪,以后對于同樣的Select語句,將直接從緩沖區(qū)中讀取結果空猜,以節(jié)省查詢時間绽慈,提高SQL查詢的效率。
緩存更新問題
方案1:需要操作人員去操作辈毯,或者定時調度
-
主動
:后臺點擊更新緩存按鈕坝疼,從DB查找最新數據集合,刪除原緩存數據谆沃,存儲新數據到緩存钝凶; -
問題
:更新過程中刪除掉緩存后剛好有業(yè)務在查詢,那么這個時候返回的數據會是空唁影,會影響用戶體驗耕陷。
方案2:由用戶觸發(fā)更新
-
被動
:前臺獲取數據時發(fā)現(xiàn)沒有緩存數據就會去數據庫同步數據到緩存掂名; -
問題
:當并發(fā)請求獲取緩存數據不存在的時候,就會產生并發(fā)的查詢數據的操作(大量用戶同時去數據庫查詢數據)哟沫。
方案3:提前加載好數據
-
主動
:后臺點擊更新緩存按鈕饺蔑,從DB查找最新數據集合,這里不刪除緩存嗜诀,通過遍歷數據覆蓋和刪除掉無效的數據猾警; -
問題
:邏輯相對麻煩,而且更新機制無法通用隆敢。
關于一級緩存和二級緩存
為了分清這兩個概念发皿,我們先了解一下RAM。RAM和ROM相對的拂蝎,RAM是掉電以后穴墅,其中的信息就消失那一種,ROM在掉電以后信息也不會消失那一種匣屡。
RAM又分兩種封救,一種是靜態(tài)RAM,SRAM捣作;一種是動態(tài)RAM誉结,DRAM。前者的存儲速度要比后者快很多券躁,我們現(xiàn)在使用的內存一般都是動態(tài)RAM惩坑。
緩存通常都是靜態(tài)RAM,速度是非常的快也拜,但是靜態(tài)RAM集成度低(存儲相同的數據以舒,靜態(tài)RAM的體積是動態(tài)RAM的6倍),價格高(同容量的靜態(tài)RAM是動態(tài)RAM的四倍)慢哈。
由此可見蔓钟,擴大靜態(tài)RAM作為緩存是一個非常愚蠢的行為,這樣就有了一個折中的辦法卵贱,不擴大原來的靜態(tài)RAM緩存滥沫,而是增加一些高速動態(tài)RAM作為緩存。這些高速動態(tài)RAM速度要比常規(guī)動態(tài)RAM快键俱,但比原來的靜態(tài)RAM緩存慢兰绣,我們把原來的靜態(tài)RAM緩存叫做一級緩存,而把后來增加的動態(tài)RAM叫二級緩存编振。
一級緩存和二級緩存中的內容都是內存中訪問頻率高的數據的復制品(映射)缀辩,它們的存在都是為了減少高速CPU對慢速內存的訪問。通常CPU找數據或指令的順序是:先到一級緩存中找,找不到再到二級緩存中找臀玄,找不到再到內存中找瓢阴,再找不到就要到硬盤中去找了。