集群環境中資料庫與緩存的三板斧

一般情況下,緩存是很多領域的概念,在本文中,我們僅討論常規資料庫應用中緩存與資料庫的關係。

一般情況下的查詢

套路:

  • 讀: 讀緩存 ,成功則返回數據 ,緩存MISS 則讀資料庫,設置緩存。
  • 寫: 寫資料庫,成功則更新緩存。

應用場景:

  • 數據量有限,更新不頻繁
  • 允許一段時間內的數據不一致
  • 採用短時間過期緩存,降低資料庫訪問頻次,自動淘汰數據

可能出現的常規問題:

  • 如果使用的是外部緩存,則會遇到更新緩存失敗的情況,導致用戶修改數據後,在過期前一直讀取到舊數據(一般可以接受),但用戶有可能會看到數據的抖動。
  • 如果使用的內存或本地文件的緩存,則會遇到集群節點間數據差異導致訪問出現數據的抖動,同時有可能會遇到內存佔用過大的情況。

解決方法(指的是儘可能防止數據抖動並儘可能保證數據修改能被訪問緩存時觀測到):

  • 使用二級緩存,結合會話粘性技術保證同一用戶看到的數據不發生抖動。
  • 內存或本地文件緩存,修改時觸發全局事件,通知到每個節點淘汰相應緩存數據。

以上兩個方法均有失敗的可能性,所以這種方法必須結合有限的過期時間才能保證數據的最終一致性,防止災難的發生。

應對不定時突然的大流量

比如容易出現不定期的熱點情況,同時數據量比較大,用戶訪問頻繁,多是用戶自己的數據,如果依賴較短時間過期的緩存,緩存命中率低,此時資料庫IOPS可能無法應對。

讀頻繁:

套路(來自58技術文章的分享):

  • 結合RPC的負載均衡技術按數據ID進行哈希分片,使同一數據在一段時間內位於一個節點上處理,而後讓該數據的寫與資料庫讀互斥。
  • 讀: 讀緩存 ,成功則返回數據 ,緩存MISS 則讀資料庫,設置緩存。
  • 寫: 淘汰緩存數據,寫資料庫,成功則更新緩存。

問題:依賴具體的技術細節。

改動頻繁:

套路: 寫緩存,通過其他手段(如隊列)入庫,削峰填谷

問題:緩存重啟有可能丟數據(使用Redis會好一些),隊列服務崩潰或者異常時,可能要設計好同步緩存數據的服務。

可預期範圍內短時間內高速大量訪問的需求

如每天定時推送給終端客戶信息,有可能需要在極短時間內的高QPS數據的查詢。

套路:

  • 如在N時間需要高QPS數據的查詢
  • 計算資料庫效率,提前在M時間預熱數據到緩存,如10點推送,8點開始預熱數據到緩存
  • 從M時間到N時間內對數據的修改觸發事件更新緩存內容。

以上是我在萌小助工作實踐過程中總結的緩存經驗,但是對於寫程序這件事兒來說沒有萬能套路,只有根據具體業務的分析和各種妥協。

推薦閱讀:

aredis —— 一款高效的非同步 redis 客戶端
No-SQL資料庫中的事務性設計
200G的數據,主要是查詢操作,酷睿I5個人PC,應該選擇什麼資料庫來存儲?
redis是個單線程的程序,為什麼會這麼快呢?每秒10000?這個有點不解,具體是快在哪裡呢?EPOLL?內存?

TAG:缓存 | Redis | Memcached |