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之後,每次都還要去資料庫再查詢一遍,發現資料庫也沒有,相當於進行了兩次無用的查詢。這樣請求就可以繞過快取直接查資料庫,如果這個時候有人想惡意攻擊系統,就可以故意使用空值或其他不存在的值進行頻繁請求,那麼就會對資料庫造成比較大的壓力。
這種現象的原因其實很好理解,業務邏輯裡面如果用戶對某些資訊還沒有進行相應的操作或處理,那對應的存放資訊的資料庫或快取中自然也沒有對應的數據,也就容易出現上述問題。
針對快取穿透,一般有以下三種處理方案:
根據資料不同量級,可以有以下幾種做法:
資料量不大:專案啟動的時候自動進行載入。
資料量較大:後台定時會刷新快取。
資料量極大:只針對熱點資料進行預先載入快取操作。
一般做法有以下兩種:
以上是Redis快取三大異常如何處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!