原文地址 http://robbin.javaeye.com/blog/78234
其中很多人談到了緩存命中率的問(wèn)題,應(yīng)用緩存的命中率取決于很多的因素:
1、應(yīng)用場(chǎng)景
是OLTP還是OLAP應(yīng)用,即使是OLTP,也要看訪問(wèn)的頻度,一個(gè)極少被訪問(wèn)到的緩存等于沒(méi)有什么效果。一般來(lái)說(shuō),互聯(lián)網(wǎng)網(wǎng)站是非常適合緩存 應(yīng)用的場(chǎng)景。
2、緩存的粒度
毫無(wú)疑問(wèn),緩存的粒度越小,命中率就越高,對(duì)象緩存是目前緩存粒度最小的,因此被命中的幾率更高。舉個(gè)例子來(lái)說(shuō)吧:你訪問(wèn)當(dāng)前這個(gè)頁(yè)面,瀏覽帖 子,那么對(duì)于ORM來(lái)說(shuō),需要發(fā)送n條SQL,取各自帖子user的對(duì)象。很顯然,如果這個(gè)user在其他帖子里面也跟貼了,那么在訪問(wèn)那個(gè)帖子的時(shí)候, 就可以直接從緩存里面取這個(gè)user對(duì)象了。
3、架構(gòu)的設(shè)計(jì)
架構(gòu)的設(shè)計(jì)對(duì)于緩存命中率也有至關(guān)重要的影響。例如你應(yīng)該如何去盡量避免緩存失效的問(wèn)題,如何盡量提供頻繁訪問(wèn)數(shù)據(jù)的緩存問(wèn)題,這些都是考驗(yàn)架構(gòu) 師水平的地方。再舉個(gè)例子來(lái)說(shuō),對(duì)于論壇,需要記錄每個(gè)topic的瀏覽次數(shù),所以每次有人訪問(wèn)這個(gè)topic,那么topic表就要update一次, 這意味著什么呢?對(duì)于topic的對(duì)象緩存是無(wú)效的,每次訪問(wèn)都要更新緩存。那么可以想一些辦法,例如增加一個(gè)中間變量記錄點(diǎn)擊次數(shù),每累計(jì)一定的點(diǎn)擊, 才更新一次數(shù)據(jù)庫(kù),從而減低緩存失效的頻率。
4、緩存的容量和緩存的有效期
緩存太小,造成頻繁的LRU,也會(huì)降低命中率,緩存的有效期太短也會(huì)造成緩存命中率下降。
所以緩存命中率問(wèn)題不能一概而論,一定說(shuō)命中率很低或者命中率很高。但是如果你對(duì)于緩存的掌握很精通,有意識(shí)的去調(diào)整應(yīng)用的架構(gòu),去分解緩存的粒 度,總是會(huì)帶來(lái)很高的命中率的。
這里我可以舉一個(gè)實(shí)際的案例,JavaEye2.0網(wǎng)站在使用對(duì)象緩存之前,通過(guò)MySQL的監(jiān)控工具進(jìn)行觀察,在連續(xù)24小時(shí)的平均每秒發(fā)送 SQL條數(shù)超過(guò)了200條,在使用對(duì)象緩存之后,連續(xù)24小時(shí)的平均每秒發(fā)送SQL條數(shù)下降到了120條左右,幾乎下降了一半。
考慮到很多SQL都是分頁(yè)語(yǔ)句,關(guān)聯(lián)查詢,條件查詢,集合操作,都是不能被緩存的SQL,而真正能夠被緩存的SQL只有根據(jù)主鍵查詢對(duì)象和對(duì)象關(guān) 聯(lián)對(duì)象的查詢。所以真正能夠被緩存的SQL估計(jì)最多占所有SQL的60%。所以換算下來(lái),應(yīng)用緩存的命中率之高,已經(jīng)相當(dāng)驚人了。
不過(guò)這里要提醒的一點(diǎn),有將近一半的SQL都被緩存,不意味著性能可以提升一倍。這是因?yàn)槟軌虮痪彺娴亩际前凑罩麈I查詢單條記錄的SQL,這些 SQL本身即使發(fā)送到數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)造成的壓力也沒(méi)有想像的那么大。真正對(duì)數(shù)據(jù)庫(kù)造成龐大壓力的正是那些沒(méi)有索引的大表查詢,和造成了全表掃描的關(guān)聯(lián)查 詢,這些一旦涉及到全表掃描的查詢,才是性能的真正殺手。當(dāng)然了,不管怎么說(shuō),通過(guò)使用對(duì)象緩存,是毫無(wú)疑問(wèn)可以大幅度降低數(shù)據(jù)庫(kù)的負(fù)載壓力的,有效提升 web應(yīng)用的性能的。
關(guān)于這一點(diǎn),我再給出一組數(shù)據(jù)來(lái)加深大家的印象,通過(guò)使用操作系統(tǒng)網(wǎng)絡(luò)工具進(jìn)行統(tǒng)計(jì):
JavaEye網(wǎng)站web server的端口每秒數(shù)據(jù)流量是2MB;
JavaEye網(wǎng)站的MySQL數(shù)據(jù)庫(kù)端口的每秒數(shù)據(jù)流量是1.2MB;
而網(wǎng)站的memcached的端口每秒的數(shù)據(jù)流量高達(dá)5MB。