第一種情況,也是最常用的情況,就是獲取一個帖子對應的回復,sql語句應該是象 select id from T where topicId=2008 order by createTime desc limit 0,5 select id from T where topicId=2008 order by createTime desc limit 5,5 select id from T where topicId=2008 order by createTime desc limit 10,5 的樣子,那么這種列表很顯然用topicId做散列是最好的,把上面三個列表緩存(可以是N個)都散列到key是topicId=2008這一個Map中,當id是2008的帖子有新的回復時,系統(tǒng)自動把key是topicId=2008的散列Map清除即可。由于這種散列不需要遍歷,因此可以設置成很大,例如100000,這樣10萬個帖子對應的所有回復列表都可以緩存起來,當有一個帖子有新的回復時,其余99999個帖子對應的回復列表都不會動,緩存的命中率極高。
第二種情況,就是后臺需要顯示最新的回復,sql語句應該是象 select id from T order by createTime desc limit 0,50 的樣子,這種情況不需要散列,因為后臺不可能有太多人訪問,常用列表也不會太多,所以直接放到通用列表緩存B中即可。
第三種情況,獲取一個用戶的回復,sql語句象 select id from T where userId=2046 order by createTime desc limit 0,15 select id from T where userId=2046 order by createTime desc limit 15,15 select id from T where userId=2046 order by createTime desc limit 30,15 的樣子,那么這種列表和第一種情況類似,用userId做散列即可。
第四種情況,獲取一個用戶對某個帖子的回復,sql語句象 select id from T where topicId=2008 and userId=2046 order by createTime desc limit 0,15 select id from T where topicId=2008 and userId=2046 order by createTime desc limit 15,15 的樣子,這種情況比較少見,一般以topicId=2008為準,也放到key是topicId=2008這個散列Map里即可。
列表緩存B是: Key鍵(String型) Value值(ArrayList型) from T order by createTime desc limit 0,50 ArrayList,對應取出來的所有id from T order by createTime desc limit 50,50 ArrayList,對應取出來的所有id from T order by createTime desc limit 100,50 ArrayList,對應取出來的所有id ……
總結:這種緩存思路可以存儲大規(guī)模的列表,緩存命中率極高,因此可以承受超大規(guī)模的應用,但是需要技術人員根據(jù)自身業(yè)務邏輯來配置需要做散列的字段,一般用一個表的索引鍵做散列(注意順序,最散的字段放前面),假設以userId為例,可以存儲N個用戶的M種列表,如果某個用戶的相關數(shù)據(jù)發(fā)生變化,其余N- 1個用戶的列表緩存紋絲不動。以上說明的都是如何緩存列表,緩存長度和緩存列表思路完全一樣,如緩存象select count(*) from T where topicId=2008這樣的長度,也是放到topicId=2008這個散列Map中。如果再配合好使用mysql的內(nèi)存表和memcached,加上F5設備做分布式負載均衡,該系統(tǒng)對付像1000萬IP/天這種規(guī)模級的應用都足夠了,除搜索引擎外一般的應用網(wǎng)站到不了這種規(guī)模。