首頁  >  文章  >  資料庫  >  Redis快取三大異常如何處理

Redis快取三大異常如何處理

WBOY
WBOY轉載
2023-05-27 11:28:33994瀏覽

    一、背景

    Redis是完全開源的、遵守BSD協定的、高效能的key-value資料結構儲存系統,它支援資料的持久化,可以將記憶體中的資料保存在磁碟中,而且不僅僅支援簡單的key-value類型的數據,同時還提供list,set,zset,hash等資料結構的存儲,功能十分強大,Redis也支援資料的備份,即master-slave模式的資料備份,進而提高可用性。快速的讀寫速度是最關鍵的,因為作為我們日常開發中最常使用的快取方案,它得到了廣泛的應用。但在實際應用過程中,它會存在快取雪崩、快取擊穿和快取穿透等異常情況,如果忽視這些情況可能會帶來災難性的後果,以下主要對這些快取異常和常見處理方案進行相應分析與總結。

    二、快取雪崩

    (一)是什麼

    有一段時間本應在redis快取中處理的大量請求,都發送到了資料庫進行處理,導致對資料庫的壓力迅速增大,嚴重時甚至可能導致資料庫崩潰,導致整個系統崩潰,就像雪崩一樣,引發連鎖效應,所以叫緩存雪崩。

    (二)為什麼

    上述情況出現的常見原因主要有以下兩點:

    • 大量快取資料同時過期,導致本應請求到快取的需重新從資料庫中取得資料。

    • redis本身出現故障,無法處理請求,那自然會再請求到資料庫那裡。

    (三)怎麼辦

    針對大量快取資料同時過期的情況:

    • 實際設定過期時間時,應盡量避免大量key同時過期的場景,如果真的有,那就透過隨機、微調、均勻設定等方式設定過期時間,從而避免同一時間過期。

    • 新增互斥鎖,使得建置快取的操作不會在同一時間進行。

    • 雙key策略,主key是原始緩存,備key為拷貝緩存,主key失效時,可以存取備key,主key快取失效時間設定為短期,備key設置為長期。

    • 後台更新快取策略,採用定時任務或訊息佇列的方式進行redis快取更新或移除等。

    針對redis本身出現故障的情況:

    • #在預防層面,可以透過主從節點的方式構建高可用的集群,也就是實現主Redis實例掛掉後,能有其他從庫快速切換為主庫,繼續提供服務。

    • 一旦發生了事件,為了避免資料庫遭到過多要求而崩潰,可採用服務熔斷或要求限流策略。當然服務熔斷相對粗暴一些,停止服務直到redis服務恢復,請求限流相對溫和一些,保證一些請求可以處理,不是一刀切,不過還是看具體業務情況選擇合適的處理方案。

    三、快取擊穿

    (一)是什麼

    快取擊穿一般出現在高並發系統中,是大量並發用戶同時請求到緩存中沒有但數據庫中有的數據,也就是同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大。和快取雪崩不同的是,快取擊穿指並發查同一條數據,快取雪崩是不同數據都過期了,很多數據都查不到從而查資料庫。

    (二)為什麼

    這種情況其實一般出現的原因就是某個熱點數據快取過期,由於是熱點數據,請求並發量又大,所以過期的時候還是會有大量請求同時過來,來不及更新快取就全部打到資料庫那邊了。

    (三)怎麼辦

    針對這種情況有兩種常見的處理方案:

    • ##簡單粗暴的熱點資料不設定過期時間,這樣不會過期,自然就不會出現上述情況了,如果後續想清理,可以透過後台進行清理。

    • 新增互斥鎖,也就是當過期之後,除了請求過來的第一個查詢的請求可以取得到鎖請求到資料庫,並再次更新到快取中,其他的會被阻塞住,直到鎖被釋放,同時新的快取也被更新上去了,後續請求又會請求到快取上,這樣就不會出現快取擊穿了。

    四、快取穿透

    (一)是什麼

    快取穿透是指資料既不在redis中,也不在資料庫中,這樣就導致每次請求過來的時候,在快取中找不到對應key之後,每次都還要去資料庫再查詢一遍,發現資料庫也沒有,相當於進行了兩次無用的查詢。這樣請求就可以繞過快取直接查資料庫,如果這個時候有人想惡意攻擊系統,就可以故意使用空值或其他不存在的值進行頻繁請求,那麼就會對資料庫造成比較大的壓力。

    (二)為什麼

    這種現象的原因其實很好理解,業務邏輯裡面如果用戶對某些資訊還沒有進行相應的操作或處理,那對應的存放資訊的資料庫或快取中自然也沒有對應的數據,也就容易出現上述問題。

    (三)怎麼辦

    針對快取穿透,一般有以下三種處理方案:

    • ##非法請求的限制,主要是指參數校驗、鑑權校驗等,從而一開始就把大量的非法請求攔截在外,這在實際業務開發中是必要的手段。

    • 快取空值或預設值,如果從緩訪問不到的數據,在資料庫中也沒有取到,那我們仍然把這個空結果進行緩存,同時設定一個較短的過期時間。透過這個設定的預設值存放到緩存,這樣第二次到快取中獲取就有值了,而不會繼續存取資料庫,可以防止有大量惡意請求是重複用同一個key進行攻擊。

    • 使用布隆篩選器快速判斷資料是否存在。那什麼是布林過濾器呢,簡單來說,就是可以引入了多個相互獨立的雜湊函數,保證在給定的空間和誤判率下,完成元素判重。因為我們知道,存在hash碰撞這樣一種情況,那麼如果只使用一個hash函數,則碰撞衝突的機率明顯會變大,那為了減少這種衝突,我們可以多引入幾個hash函數,而布隆過濾器演算法的核心思想就是利用多個不同的hash函數來解決這樣一種衝突。它的優點是空間效率高,查詢時間短,遠超其他演算法,而它的缺點就是會存在一定的誤辨識率,它不能完全保證請求過來的key,透過布隆過濾器的校驗,就一定有這個數據,畢竟理論上還是會存在衝突情況,無論機率多小。但是,只要沒有通過布隆過濾器的校驗,那麼這個key就一定不存在,只要利用這一點其實就已經可以過濾掉大部分不存在的key的請求了,在正常場景下已然足夠了。

    五、其他

    除了上述三種常見的Redis快取例外問題之外,還常聽到的有快取預熱和快取降級兩個名詞,與其說是異常問題,不如說是兩種的最佳化處理方法。

    (一)快取預熱

    在系統上線前後,快取預熱會將相關的快取資料直接載入至快取系統,不需要依賴使用者操作。這樣可以避免在使用者請求時先查詢資料庫,然後再將資料快取的問題。使用者直接查詢事先被預熱的快取數據,這樣可以避免那麼系統上線初期,對於高並發的流量,都會訪問到資料庫中, 對資料庫造成流量的壓力。

    根據資料不同量級,可以有以下幾種做法:

    • 資料量不大:專案啟動的時候自動進行載入。

    • 資料量較大:後台定時會刷新快取。

    • 資料量極大:只針對熱點資料進行預先載入快取操作。

    (二)快取降級

    快取降級是指當快取失效或快取服務出現問題時,為了防止快取服務故障,導致資料庫跟著一起發生雪崩問題,所以也不去存取資料庫,但因為一些原因,仍然想要保證服務還是基本上可用的,雖然肯定會是有損服務。因此,對於不重要的快取數據,我們可以採取服務降級策略。

    一般做法有以下兩種:

    • 直接存取記憶體部分的資料快取。

    • 直接傳回系統設定的預設值。

    • #

    以上是Redis快取三大異常如何處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除