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