<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis中緩存雪崩、緩存穿透等問題的解決方案

          共 2212字,需瀏覽 5分鐘

           ·

          2021-12-14 15:41

          緩存雪崩

          緩存雪崩是指緩存同一時間大面積的失效,所以,后面的請求都會落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。


          解決方案

          1. 緩存數(shù)據(jù)的過期時間設(shè)置隨機(jī),防止同一時間大量數(shù)據(jù)過期現(xiàn)象發(fā)生。

          2. 一般并發(fā)量不是特別多的時候,使用最多的解決方案是加鎖排隊(duì)。

          3. 給每一個緩存數(shù)據(jù)增加相應(yīng)的緩存標(biāo)記,記錄緩存的是否失效,如果緩存標(biāo)記失效,則更新數(shù)據(jù)緩存。


          緩存穿透

          緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),導(dǎo)致所有的請求都落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。


          解決方案

          1. 接口層增加校驗(yàn),如用戶鑒權(quán)校驗(yàn),id做基礎(chǔ)校驗(yàn),id<=0的直接攔截;

          2. 從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到,這時也可以將key-value對寫為key-null,緩存有效時間可以設(shè)置短點(diǎn),如30秒(設(shè)置太長會導(dǎo)致正常情況也沒法使用)。這樣可以防止攻擊用戶反復(fù)用同一個id暴力攻擊

          3. 采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的 bitmap 中,一個一定不存在的數(shù)據(jù)會被這個 bitmap 攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力


          附加

          對于空間的利用到達(dá)了一種極致,那就是Bitmap和布隆過濾器(Bloom Filter)。

          Bitmap:典型的就是哈希表

          缺點(diǎn)是,Bitmap對于每個元素只能記錄1bit信息,如果還想完成額外的功能,恐怕只能靠犧牲更多的空間、時間來完成了。


          布隆過濾器(推薦)


          就是引入了k(k>1)k(k>1)個相互獨(dú)立的哈希函數(shù),保證在給定的空間、誤判率下,完成元素判重的過程。

          它的優(yōu)點(diǎn)是空間效率和查詢時間都遠(yuǎn)遠(yuǎn)超過一般的算法,缺點(diǎn)是有一定的誤識別率和刪除困難。

          Bloom-Filter算法的核心思想就是利用多個不同的Hash函數(shù)來解決“沖突”。

          Hash存在一個沖突(碰撞)的問題,用同一個Hash得到的兩個URL的值有可能相同。為了減少沖突,我們可以多引入幾個Hash,如果通過其中的一個Hash值我們得出某元素不在集合中,那么該元素肯定不在集合中。只有在所有的Hash函數(shù)告訴我們該元素在集合中時,才能確定該元素存在于集合中。這便是Bloom-Filter的基本思想。

          Bloom-Filter一般用于在大數(shù)據(jù)量的集合中判定某元素是否存在。


          緩存擊穿

          緩存擊穿是指緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)(一般是緩存時間到期),這時由于并發(fā)用戶特別多,同時讀緩存沒讀到數(shù)據(jù),又同時去數(shù)據(jù)庫去取數(shù)據(jù),引起數(shù)據(jù)庫壓力瞬間增大,造成過大壓力。和緩存雪崩不同的是,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫。

          解決方案

          1. 設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期。

          2. 加互斥鎖,互斥鎖


          緩存預(yù)熱

          緩存預(yù)熱就是系統(tǒng)上線后,將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)。這樣就可以避免在用戶請求的時候,先查詢數(shù)據(jù)庫,然后再將數(shù)據(jù)緩存的問題!用戶直接查詢事先被預(yù)熱的緩存數(shù)據(jù)!

          解決方案

          1. 直接寫個緩存刷新頁面,上線時手工操作一下;

          2. 數(shù)據(jù)量不大,可以在項(xiàng)目啟動的時候自動進(jìn)行加載;

          3. 定時刷新緩存;


          緩存降級

          當(dāng)訪問量劇增、服務(wù)出現(xiàn)問題(如響應(yīng)時間慢或不響應(yīng))或非核心服務(wù)影響到核心流程的性能時,仍然需要保證服務(wù)還是可用的,即使是有損服務(wù)。系統(tǒng)可以根據(jù)一些關(guān)鍵數(shù)據(jù)進(jìn)行自動降級,也可以配置開關(guān)實(shí)現(xiàn)人工降級。


          緩存降級的最終目的是保證核心服務(wù)可用,即使是有損的。而且有些服務(wù)是無法降級的(如加入購物車、結(jié)算)。


          在進(jìn)行降級之前要對系統(tǒng)進(jìn)行梳理,看看系統(tǒng)是不是可以丟卒保帥;從而梳理出哪些必須誓死保護(hù),哪些可降級;比如可以參考日志級別設(shè)置預(yù)案:


          1. 一般:比如有些服務(wù)偶爾因?yàn)榫W(wǎng)絡(luò)抖動或者服務(wù)正在上線而超時,可以自動降級;

          2. 警告:有些服務(wù)在一段時間內(nèi)成功率有波動(如在95~100%之間),可以自動降級或人工降級,并發(fā)送告警;

          3. 錯誤:比如可用率低于90%,或者數(shù)據(jù)庫連接池被打爆了,或者訪問量突然猛增到系統(tǒng)能承受的最大閥值,此時可以根據(jù)情況自動降級或者人工降級;

          4. 嚴(yán)重錯誤:比如因?yàn)樘厥庠驍?shù)據(jù)錯誤了,此時需要緊急人工降級。


          服務(wù)降級的目的,是為了防止Redis服務(wù)故障,導(dǎo)致數(shù)據(jù)庫跟著一起發(fā)生雪崩問題。因此,對于不重要的緩存數(shù)據(jù),可以采取服務(wù)降級策略,例如一個比較常見的做法就是,Redis出現(xiàn)問題,不去數(shù)據(jù)庫查詢,而是直接返回默認(rèn)值給用戶。


          熱點(diǎn)數(shù)據(jù)和冷數(shù)據(jù)

          熱點(diǎn)數(shù)據(jù),緩存才有價值


          對于冷數(shù)據(jù)而言,大部分?jǐn)?shù)據(jù)可能還沒有再次訪問到就已經(jīng)被擠出內(nèi)存,不僅占用內(nèi)存,而且價值不大。頻繁修改的數(shù)據(jù),看情況考慮使用緩存


          對于熱點(diǎn)數(shù)據(jù),比如我們的某IM產(chǎn)品,生日祝福模塊,當(dāng)天的壽星列表,緩存以后可能讀取數(shù)十萬次。再舉個例子,某導(dǎo)航產(chǎn)品,我們將導(dǎo)航信息,緩存以后可能讀取數(shù)百萬次。


          數(shù)據(jù)更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。


          那存不存在,修改頻率很高,但是又不得不考慮緩存的場景呢?有!比如,這個讀取接口對數(shù)據(jù)庫的壓力很大,但是又是熱點(diǎn)數(shù)據(jù),這個時候就需要考慮通過緩存手段,減少數(shù)據(jù)庫的壓力,比如我們的某助手產(chǎn)品的,點(diǎn)贊數(shù),收藏數(shù),分享數(shù)等是非常典型的熱點(diǎn)數(shù)據(jù),但是又不斷變化,此時就需要將數(shù)據(jù)同步保存到Redis緩存,減少數(shù)據(jù)庫壓力。


          緩存熱點(diǎn)key

          緩存中的一個Key(比如一個促銷商品),在某個時間點(diǎn)過期的時候,恰好在這個時間點(diǎn)對這個Key有大量的并發(fā)請求過來,這些請求發(fā)現(xiàn)緩存過期一般都會從后端DB加載數(shù)據(jù)并回設(shè)到緩存,這個時候大并發(fā)的請求可能會瞬間把后端DB壓垮。


          解決方案

          對緩存查詢加鎖,如果KEY不存在,就加鎖,然后查DB入緩存,然后解鎖;其他進(jìn)程如果發(fā)現(xiàn)有鎖就等待,然后等解鎖后返回數(shù)據(jù)或者進(jìn)入DB查詢


          往日精選文章

          Redis哨兵機(jī)制
          Redis很牛逼很秀!輕松實(shí)現(xiàn)實(shí)時訂閱推送
          Redis 高級面試題 學(xué)會這些還怕進(jìn)不了大廠?
          一文掌握Redis主從復(fù)制、哨兵、Cluster三種集群模式
          2020 年最新版 68 道Redis面試題,20000 字干貨,趕緊收藏起來備用!


          瀏覽 42
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  理伦不卡在线 | 男人天堂久热 | 五月天综合中文网 | 大香伊人中文字幕 | 日韩色视频在线观看 |