Redis從入門到精通(九、Redis使用中常見的問題)

Redis 在為程序帶來性能提高的同時,也會有缺點,這些都是我們需要考慮的,比如: Redis與持久化數據庫的數據一致性問題,緩存雪崩問題,緩存穿透問題,緩存擊穿問題等,本文就上述幾個問題,簡單的闡述一下解決思路。

緩存穿透

如果我們的查詢數據路線是: App -> Redis -> MySQL(或其它RDBS),正常情況下,我們查詢數據都會在Redis命中,Redis未命中的情況下才去查詢MySQL,然后將查詢到的數據寫入到Redis中,這樣下次就直接可以在Redis層命中。

那么如果查詢一條MySQL中壓根兒根本就不存在的數據,也就是緩存和數據庫都查詢不到這條數據,但是請求每次都會打到數據庫上面去。這種查詢不存在數據的現(xiàn)象我們稱為緩存穿透

解決方案(緩存穿透)

  • 將null值存入redis,設置過期時間
  • BloomFilter

第一種方案比較簡單易懂,查詢不到數據,將Null值存到Redis中,并設置上過期時間,這樣下次請求再過來,可以直接返回Null,不會再落到MySQL。

但是,針對于一些惡意攻擊,攻擊帶過來的大量key 是不存在的,那么我們采用第一種方案就會緩存大量不存在key的數據。此時我們采用第一種方案就不合適了,我們完全可以先對使用第二種方案進行過濾掉這些key。關于 BloomFilter , 下文列出簡單的描述,我們可以在應用層加一層 BloomFilter 來解決這個問題。

Bloomfilter: 布隆過濾器, 它是由一個很長的二進制向量和一系列隨機映射函數組成,布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率。即Bloom Filter報告某一元素存在于某集合中,但是實際上該元素并不在集合中。但是如果某個元素確實沒有在該集合中,那么Bloom Filter 是不會報告該元素存在于集合中的,所以不會漏報。

針對key非常多、請求重復率比較低的數據,我們就沒有必要進行緩存,使用第二種方案直接過濾掉。而對于空數據的key有限的,重復率比較高的,我們則可以采用第一種方式進行緩存。


緩存擊穿

在高并發(fā)的系統(tǒng)中,大量的請求同時查詢一個 key 時,此時這個key正好失效了,就會導致大量的請求都打到數據庫上面去。這種現(xiàn)象我們稱為緩存擊穿。

解決方案(緩存擊穿)

  • 熱點Key不設置過期時間
  • 使用 互斥鎖,在第一個查詢數據的請求上使用一個互斥鎖來鎖住它。后續(xù)線程阻塞,等第一個線程查詢到數據并做了緩存,鎖釋放后后續(xù)線程,發(fā)現(xiàn)已經有緩存了,就直接走緩存。

第一種方案使用具有局限性,需要結合業(yè)務考慮是否可以不設置過期時間。
第二種方案,由于使用了互斥鎖,所以性能肯定會差很多。


緩存雪崩

緩存雪崩的情況是說,當某一時刻發(fā)生大規(guī)模的緩存失效的情況 或者 緩存服務宕機了,會有大量的請求進來直接打到DB上面。稱為 緩存雪崩。

解決方案(緩存雪崩)

  • 保證Redis服務的高可用
  • 應用種使用本地緩存,以及限流降級等措施
  • 解決熱點數據集中失效,為每個key設置不同的過期時間

Redis 的集群是必須要做的,保證Redis服務的高可用,在應用種也要處理Redis宕機的情況,比如做出限流或者降級的措施,采用本地緩存等,讓查詢請求盡可能少的落到數據庫上。Redis的集群方案怎么來做,可以參考我之前的文章。

針對一些熱點數據集中失效的問題,可以采用設置不同的過期時間的方案,在一個基礎時間上左右浮動,例如: 30min + 3s,30min -5s .


Redis與持久層數據一致性的問題

App -> Redis -> MySQL ,App查詢請求先請求Redis,如果查詢不到再請求MySQL,查詢到數據后將數據寫入MySQL。

在這樣的一條查詢鏈路種,由于數據的寫入可能會造成Redis與MySQL數據的不一致。

比如: 數據寫入時,先寫入Redis再寫入MySQL,可能在寫入MySQL時出現(xiàn)異常,導致數據不一致,反過來也是如此。

解決方案(數據不一致)

  • 寫入時,刪除Redis中的數據

總結

在實際使用過程種還是要結合具體的業(yè)務,來從上述幾個方面來考慮程序的健壯性。最終的目的都是保護數據庫。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Redis是什么 Redis是1個內存數據庫,非關系型,基于Key-Value存儲,速度快 支持多種數據類型,St...
    Goooooooooooal閱讀 1,294評論 0 0
  • Redis用作緩存,主要兩個用途:高性能,高并發(fā),因為內存天然支持高并發(fā) 一.緩存穿透: 緩存穿透是指查詢一個一定...
    Y了個J閱讀 1,001評論 0 0
  • 今天看到一位朋友寫的mysql筆記總結,覺得寫的很詳細很用心,這里轉載一下,供大家參考下,也希望大家能關注他原文地...
    信仰與初衷閱讀 4,834評論 0 30
  • 緩存是分布式系統(tǒng)中的重要組件,主要解決高并發(fā),大數據場景下,熱點數據訪問的性能問題。提供高性能的數據快速訪問。 一...
    Java架構師Carl閱讀 1,257評論 0 23
  • 一、Redis 1、概述 Redis是速度非??斓姆顷P系型內存鍵值數據庫,可以存儲鍵和物種不同類型的值之間的映射。...
    落地生涯閱讀 842評論 0 3

友情鏈接更多精彩內容