自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

三分鐘帶你掌握緩存穿透、緩存雪崩、緩存擊穿,以及應(yīng)對方案!

數(shù)據(jù)庫 Redis
站在面試者的角度,除了熟練的掌握 redis 的使用方法以外,我們可能還需要更加深入的了解如果引入 redis 之后,系統(tǒng)中可能會發(fā)生的一些問題以及應(yīng)對辦法。

?一、介紹

每場后端面試,似乎都少不了關(guān)于 redis 的話題,比如項(xiàng)目使用過哪些分布式緩存服務(wù),為什么要使用 redis,有沒有碰到過緩存失效、緩存穿透、緩存雪崩等問題。

在前幾篇關(guān)于 redis 的介紹文章中,我們說到項(xiàng)目中之所以會引入分布式緩存服務(wù),主要是為了解決集群環(huán)境下,內(nèi)存數(shù)據(jù)不共享的問題,比如 session 會話,以及一些字典緩存等等,在當(dāng)前服務(wù)器的內(nèi)存中存儲,在另一臺服務(wù)器中難以獲取查詢的問題,通過引入緩存服務(wù),將緩存數(shù)據(jù)統(tǒng)一歸一到一個(gè)服務(wù)器里面,以解決系統(tǒng)中內(nèi)存數(shù)據(jù)不共享的問題,同時(shí)緩存性能也不會受到很大影響。

當(dāng)然軟件開源市場上,也有很多的分布式緩存服務(wù),比如比較有名的有 redis、memcached 等,相對比 memcached,redis 各項(xiàng)指標(biāo)都要比 memcached 強(qiáng)很多,Redis 號稱能讀的速度是 110000 次/s,寫的速度是 81000次/s,無數(shù)的實(shí)踐證明 redis 確實(shí)是當(dāng)前一款非常高性能的內(nèi)存數(shù)據(jù)庫。

站在面試官的角度,軟件系統(tǒng)的技術(shù)選型以及以上的相關(guān)技術(shù)問題,在實(shí)際的生產(chǎn)環(huán)境中確實(shí)也會發(fā)生,通過以此話題為切入點(diǎn),可以更加清晰的了解面試者是否也碰到過類似的問題,以及對應(yīng)處理的辦法。

那么站在面試者的角度,除了熟練的掌握 redis 的使用方法以外,我們可能還需要更加深入的了解如果引入 redis 之后,系統(tǒng)中可能會發(fā)生的一些問題以及應(yīng)對辦法。

今天我們一起聊聊吧。

二、常見問題

2.1、問題一:為什么存入 redis 的數(shù)據(jù),查詢失效

Redis 的所有數(shù)據(jù)都是保存在內(nèi)存中,然后不定期的通過異步方式保存到磁盤上;也可以把每一次數(shù)據(jù)變化都寫入到一個(gè)aof日志文件里面,當(dāng) redis 的服務(wù)器重啟的時(shí)候,自動從日志文件里面恢復(fù)數(shù)據(jù)到內(nèi)存中。

有哪些場景會發(fā)生緩存失效呢?總結(jié)起來有以下兩種場景:

  • 當(dāng) redis 服務(wù)器重啟的時(shí)候,可能會發(fā)生緩存失效,此時(shí)可以將 redis 的持久化方式改成AOF模式,也就是全持久化模式,但是性能會消耗很大
  • 存入redis 的數(shù)據(jù),設(shè)置了自動過期時(shí)間,這種情況可以重新調(diào)整過期時(shí)間

2.2、問題二:緩存與數(shù)據(jù)庫的數(shù)據(jù)不一致

通常情況下我們使用緩存,其中有一個(gè)很重要的目的就是降低數(shù)據(jù)庫的訪問壓力,比如商品的信息查詢,優(yōu)先是從緩存中查詢,如果沒有,再從數(shù)據(jù)庫里面查詢。

對于既有數(shù)據(jù)庫寫入又有緩存操作的接口,一般分為兩種情況執(zhí)行。

  • 先寫入數(shù)據(jù)庫,再操作緩存。這種情況下如果數(shù)據(jù)庫操作成功,緩存操作失敗就會導(dǎo)致緩存和數(shù)據(jù)庫不一致
  • 先操作緩存,再寫入數(shù)據(jù)庫。這種情況下如果緩存操作成功,數(shù)據(jù)庫操作失敗也會導(dǎo)致數(shù)據(jù)庫和緩存不一致

大部分情況下,緩存理論上都是需要可以從數(shù)據(jù)庫恢復(fù)出來的,所以基本上采取第一種順序都是不會有問題的,但是無法保證數(shù)據(jù)庫和緩存完全一致。

也就是說,使用緩存,就可能會出現(xiàn)緩存與數(shù)據(jù)庫不一致的情況,只是說這種幾幾率的情況有多大。

針對那些必須保證數(shù)據(jù)庫和緩存一致的情況,通常是不建議使用緩存的,直接從數(shù)據(jù)庫查詢。

2.3、問題三:什么是緩存穿透

緩存穿透,表示惡意用戶頻繁的模擬請求緩存中不存在的數(shù)據(jù),此時(shí)如果有大量的接口請求,短時(shí)間內(nèi)會直接落在了數(shù)據(jù)庫上,緩存被擊穿,導(dǎo)致數(shù)據(jù)庫性能急劇下降,最終影響服務(wù)整體的性能。

這個(gè)在實(shí)際項(xiàng)目中很容易遇到,如搶購活動、秒殺活動、搶優(yōu)惠券等接口 API 被大量的惡意用戶刷,導(dǎo)致短時(shí)間內(nèi)數(shù)據(jù)庫宕機(jī)。對于緩存擊穿的問題,有以下幾種解決方案。

  • 使用分布式鎖排隊(duì)。當(dāng)從緩存中獲取數(shù)據(jù)失敗時(shí),給當(dāng)前接口加上鎖,從數(shù)據(jù)庫中加載完數(shù)據(jù)并寫入后再釋放鎖。若其它線程獲取鎖失敗,則等待一段時(shí)間后再重試。
  • 使用布隆過濾器。將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap?中,一個(gè)一定不存在的數(shù)據(jù)會被這個(gè)bitmap攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力
  • 對空結(jié)果進(jìn)行緩存。如果一個(gè)查詢返回的數(shù)據(jù)為空,我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存,但它的過期時(shí)間會很短,最長不超過五分鐘,這樣第二次到緩存中獲取就有值了,而不會繼續(xù)訪問數(shù)據(jù)庫,簡單粗暴好使。

2.4、問題四:什么是緩存雪崩

緩存雪崩,簡單的說就是在短時(shí)間內(nèi)有大量緩存失效,如果這期間有大量的請求發(fā)生,同樣也有可能會導(dǎo)致數(shù)據(jù)庫發(fā)生宕機(jī)。在 Redis 機(jī)群的數(shù)據(jù)分布算法上如果使用的是傳統(tǒng)的 hash 取模算法,在增加或者移除 Redis 節(jié)點(diǎn)的時(shí)候就會出現(xiàn)大量的緩存臨時(shí)失效的情形。

對于緩存雪崩的問題,有以下幾種解決方案。

  • 像解決緩存穿透一樣加鎖排隊(duì)
  • 建立備份緩存。比如緩存 A 和緩存 B,A 設(shè)置超時(shí)時(shí)間,B 不設(shè)值超時(shí)時(shí)間,先從 A 讀緩存,A 沒有讀 B,當(dāng)緩存 A 發(fā)生變化的時(shí)候,同時(shí)更新緩存 B
  • 計(jì)算數(shù)據(jù)緩存節(jié)點(diǎn)的時(shí)候采用一致性 hash 算法,這樣在節(jié)點(diǎn)數(shù)量發(fā)生改變時(shí)不會存在大量的緩存數(shù)據(jù)需要遷移的情況發(fā)生

2.5、問題五:redis 緩存會不會出現(xiàn)并發(fā)問題

首先 Redis 是單線程執(zhí)行命令的,在出現(xiàn)多個(gè) Redis Client 并發(fā)操作數(shù)據(jù)時(shí),秉承先發(fā)起先執(zhí)行的原則,其它的處于阻塞狀態(tài)。

redis 緩存并發(fā)問題,其實(shí)主要指的還是讀取數(shù)據(jù)庫數(shù)據(jù)的并發(fā)操作問題。

當(dāng)緩存過期后會從數(shù)據(jù)庫查詢數(shù)據(jù)然后再存入Redis?緩存,但是在高并發(fā)情況下,可能還沒來得及將數(shù)據(jù)庫中查出來的數(shù)據(jù)存入Redis?時(shí),其它Client?又從數(shù)據(jù)庫里查詢數(shù)據(jù)再存入Redis了。

這樣一來會造成多個(gè)請求并發(fā)的從數(shù)據(jù)庫獲取數(shù)據(jù),然后存入Redis,可能在讀取的時(shí)候,出現(xiàn)臟數(shù)據(jù)。

針對這種場景,有以下幾種解決方案。

  • 同步加鎖處理。在寫入數(shù)據(jù)庫的時(shí)候,再操作緩存這個(gè)階段,進(jìn)行加鎖處理,保證服務(wù)串行,可能會犧牲一點(diǎn)時(shí)間
  • 異步隊(duì)列串行執(zhí)行。把寫入數(shù)據(jù)庫和操作緩存的操作,放在隊(duì)列中使其串行化,讓他們一個(gè)一個(gè)的執(zhí)行,比如通過消息中間件異步執(zhí)行。
  • 使用類似SQL的樂觀鎖機(jī)制:在并發(fā)寫入Redis?緩存時(shí),把要寫入數(shù)據(jù)的版本號和時(shí)間戳與Redis?中的數(shù)據(jù)進(jìn)行對比,如果寫入的數(shù)據(jù)時(shí)間戳或者版本號 比Redis高,則寫入;否則就不寫入

三、小結(jié)

本文主要圍繞 redis 使用中出現(xiàn)的一些場景問題,進(jìn)行一次簡單的總結(jié),如果有疏漏的地方,歡迎網(wǎng)友留言指出!

四、參考

1、博客園 - 卡斯特梅的雨傘- springboot中RedisTemplate的使用

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-10-12 14:19:05

Redis數(shù)據(jù)庫緩存

2019-11-05 14:24:31

緩存雪崩框架

2023-11-10 14:58:03

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2020-03-16 14:57:24

Redis面試雪崩

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2022-03-08 00:07:51

緩存雪崩數(shù)據(jù)庫

2022-11-18 14:34:28

2020-03-05 09:09:18

緩存原因方案

2023-04-14 07:34:19

2024-03-12 10:44:42

2024-04-18 11:43:28

緩存數(shù)據(jù)庫Redis

2020-10-13 07:44:40

緩存雪崩 穿透

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2020-10-23 10:46:03

緩存雪崩擊穿

2022-07-11 07:36:36

緩存緩存雪崩緩存擊穿

2020-12-28 12:37:36

緩存擊穿穿透

2022-02-17 09:24:11

TypeScript編程語言javaScrip
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號