快取算是各個網站、服務的標配了,如何才能設計出一套切合實際需求的快取方案,每個接觸過快取的Coder腦子裡都會有自己的答案。
**快取模組從無到有,要如何設計?
要考慮哪些因素?
如何方式設計不足?
如何防止設計過度?
如何滿足實際需求?
要明確哪些問題,才能逐步的完善出一套實現方案? **
小弟才疏學淺,希望哪位高人能提點一二,不勝感激。
================都焦了,不如割了吧=====================
我的需求:
快,有些記錄後就不會變(很少變),但每次都用的信息,每次讀DB開銷太大。
(Redis的掌握程度只有初級,後面會抓時間惡補)
自己設計:
0、要考慮到快取逾時、命中率,依需求,逐級增加快取等級;
1、(一級快取)第一期,做本地記憶體層級的緩存,直接從記憶體讀取,如果沒有,再讀DB,同時更新快取物件(DB中用View來提高查詢速度);
2、(二級快取)第二期,後期RQ增加到一定量,會需要Load Balance,此時會考慮使用Redis或Memcache方案作為二級緩存;當一級緩存未中,則讀取二級緩存,扔未中,則查詢資料庫(將存在的數據,反向全部更新)
問題:
1、如果記錄到DB中,配置參數不是單純的key-value形式,也有查詢匹配工作;並且隨著業務複雜度提升,還會有其他資料需要快取。
2、如果記錄到NoSQL/Redis中,如Redis,其資料存儲,是否只能用於“災備”,還是可以使用Redis的資料存儲,拋棄DB
3、對Redis的寫入操作,能否直接記錄到儲存上? 因為那些需要快取的數據,有些是需要手動輸入的。
擔憂:
第二期時,設計一級、二級快取是否多餘?主要是考慮 讀取Redis中的快取資訊會涉及到網路傳輸
方案:
A、使用一級、二級快取方案,但分散式部署後,一級快取中的資料是否逾時無法準確判斷;
B、放棄一級緩存,直接讀取Redis(不知道讀取Redis的開銷與直接讀取記憶體的開銷,哪個高。
放棄方案A,因為,雖然直接讀取本地內存,效率高,但是命中率不好說;
使用方案B,雖然有了網絡傳輸的損耗,但後續的第三期、第四期。 。甚至會需要Redis配置主從或分片,這時之前所擔心的網路損耗根本不算什麼。
1.只做適合的快取
2.不要為了用一些技術而用
我說下我使用Redis的情況,
1.首先使用Redis緩存靜態資料(即不變,或者很少變),那是完全OK的,而且也很合適,完全沒必要再插入一個一級緩存,使得快取查詢複雜。
2.麻煩的是使用Redis快取可變數據,即數據需要被修改,這時就會顯得很麻煩,因為目前Redis還不能完全取代DB的存儲作用,即最終的數據還是要入DB,進行持久化,這樣就牽涉到redis與db同步的問題。我在專案的解決方案是先修改Redis,然後非同步修改DB,最後DB同步到Redis,因為我快取的資料一致性需求很嚴格。
3.專案中會根據key查詢一個hash數據,但是一次請求會分開請求hash中的部分key數據,這樣為了必要每次請求去Redis獲取同一個Key多次,所以引入了一個JVM內存緩存,也就是題主說的一級緩存,目的是減少訪問Redis的次數,但是這個一級緩存的主要目的是合併多個請求同一個key的請求,最終緩存還是要以Redis為準,畢竟JVM內存很有限。
1、不應該自己去內存緩存,直接用memcache或redis。
一個cpu多個核,一般來說一個核一個worker,是內存不共享的,如果8個核,你在應用中緩存,就相當於有8個緩存。當然你可以用共享內存,但是需要處理多個worker交互問題。因此讓memcache,redis來做。
2、網路延遲很小,對http回應時間來說可以忽略不計,一般在0.1ms以下。
3、不要搞多層緩存,不夠用就加大memcache記憶體。
4、只做緩存,也就是寫的時候只寫資料庫,然後把對應的memcache快取刪除。讀的時候先memcache,失敗再資料庫,再寫memcache。