你所不知道的快取的使用場景
當你的應用扛不住,知道要使用快取了,應該怎麼做呢?
場景1:和資料庫中的資料結構保持一致,原樣快取
這種場景是最常見的場景,也是很多架構使用快取的適合,最先涉及到的場景。
基本就是資料庫裡面啥樣,我快取也啥樣,資料庫裡面有商品資訊,快取裡面也放商品資訊,唯一不同的是,資料庫裡面是全量的商品資訊,快取裡面是最熱的商品資訊。
每當應用要查詢商品資訊的時候,先查快取,快取沒有就查資料庫,查出來的結果放入快取,從而下次就查到了。
這個是快取最最經典的更新流程。這種方式簡單,直觀,很多快取的庫都預設支援這種方式。
場景2:列表排序分頁場景的快取
有時候我們需要獲得一些列表資料,並對這些資料進行排序和分頁。
例如我們想獲取點贊最多的評論,或者最新的評論,然後列出來,一頁一頁的翻下去。
在這種情況下,快取裡面的資料結構和資料庫裡面完全不一樣。
如果完全使用資料庫進行實現,則按照某種條件將所有的行查詢出來,然後按照某個欄位進行排序,然後進行分頁,一頁一頁的展示。
但是當資料量比較大的時候,這種方式往往成為瓶頸,首先涉及的資料庫行數比較多,而且排序也是個很慢的活,儘管可能有索引,分頁也是翻頁到最後,越是慢。
在快取裡面,就沒必要每行一個key了,而是可以使用Redis的列表方式進行儲存,當然列表的長短是有限制的,肯定放不下資料庫裡面這麼多,但是大家會發現其實對於所有的列表,使用者往往沒有耐心看個十頁八頁的,例如百度上搜個東西,也是有排序和分頁的,但是你每次都往後翻了嗎,每頁就十條,就算是十頁,或者一百頁,也就一千條資料,如果保持ID的話,完全放的下。
如果已經排好序,放在Redis裡面,那取出列表,翻頁就非常快了。
可以後臺有一個執行緒,非同步的初始化和重新整理快取,在快取裡面儲存一個時間戳,當有更新的時候,重新整理時間戳,非同步任務發現時間戳改變了,就重新整理快取。
場景3:計數快取
計數對於資料庫來講,是一個非常繁重的工作,需要查詢大量的行,最後得出計數的結論,當資料改變的時候,需要重新刷一遍,非常影響效能。
因此可以有一個計數服務,後端是一個快取,將計數作為結果放在快取裡面,當資料有改變的時候,呼叫計數服務增加或者減少計數,而非通過非同步資料庫count來更新快取。
計數服務可以使用Redis進行單個計數,或者hash表進行批量計數
場景4:重構維度快取
有時候資料庫裡面保持的資料的維度是為了寫入方便,而非為了查詢方便的,然而同時查詢過程,也需要處理高併發,因而需要為了查詢方便,將資料重新以另一個維度儲存一遍,或者說將多給資料庫的內容聚合一下,再儲存一遍,從而不用每次查詢的時候都重新聚合,如果還是放在資料庫,比較難維護,放在快取就好一些。
例如一個商品的所有的帖子和帖子的使用者,以及一個使用者發表過的所有的帖子就是屬於兩個維度。
這需要寫入一個維度的時候,同時非同步通知,更新快取中的另一個維度。
在這種場景下,資料量相對比較大,因而單純用記憶體快取memcached或者redis難以支撐,往往會選擇使用levelDB進行儲存,如果levelDB的效能跟不上,可以考慮在levelDB之前,再來一層memcached。
場景5:較大的詳情內容資料快取
對於評論的詳情,或者帖子的詳細內容,屬於非結構化的,而且內容比較大,因而使用memcached比較好。
