redis 緩存問題彙總

前言:在使用redis的時候,特別是大型應用,會碰到很多問題,下面就來總結一下使用redis時的常見問題html

 

1、redis爲緩存的問題redis

  一、緩存和數據庫雙寫一致性問題算法

分析:一致性問題是分佈式常見問題,還能夠再分爲最終一致性和強一致性。數據庫和緩存雙寫,就必然會存在不一致的問題。答這個問題,先明白一個前提。就是若是對數據有強一致性要求,不能放緩存。
   咱們所作的一切,只能保證最終一致性。另外,咱們所作的方案其實從根本上來講,只能說下降不一致發生的機率,沒法徹底避免。所以,有強一致性要求的數據,不能放緩存。 回答:先淘汰cache,再寫db(若是刪除緩存失敗,那就不要更新數據庫,若是說刪除緩存成功,而更新數據庫失敗,那查詢的時候只是從數據庫裏查了舊的數據而已,這樣就能保持數據庫與緩存的一致性。)

 

  二、緩存雪崩、擊穿問題 數據庫

請參考個人另外一篇文章:緩存雪崩、擊穿解決方案

  三、緩存的併發競爭問題緩存

分析:這個問題大體就是,同時有多個子系統去set一個key。這個時候要注意什麼呢?你們思考過麼。須要說明一下,博主提早百度了一下,發現答案基本都是推薦用redis事務機制。
   若是生產環境基本都是redis集羣環境,作了數據分片操做。你一個事務中有涉及到多個key操做的時候,這多個key不必定都存儲在同一個redis-server上。所以,redis的事務機制,十分雞肋。 回答: 一、若是對這個key操做,不要求順序 這種狀況下,準備一個分佈式鎖,你們去搶鎖,搶到鎖就作set操做便可,比較簡單。 二、若是對這個key操做,要求順序 通常用串行方式就行,好比隊列

 

2、redis的過時策略及內存淘汰機制併發

 

  這個問題其實至關重要,到底redis有沒用到家,這個問題就能夠看出來。好比你redis只能存5G數據,但是你寫了10G,那會刪5G的數據。
怎麼刪的,這個問題思考過麼?還有,你的數據已經設置了過時時間,可是時間到了,內存佔用率仍是比較高,有思考過緣由麼?

 

  一、redis採用的是按期刪除+惰性刪除策略。dom

  二、爲何不用定時刪除策略?分佈式

定時刪除,用一個定時器來負責監視key,過時則自動刪除。雖然內存及時釋放,可是十分消耗CPU資源。在大併發請求下,CPU要將時間應用在處理請求,而不是刪除key,所以沒有采用這一策略.

 

  三、按期刪除+惰性刪除是如何工做的呢?測試

  按期刪除,redis默認每一個100ms檢查,是否有過時的key,有過時key則刪除。須要說明的是,redis不是每一個100ms將全部的key檢查一次,
而是隨機抽取進行檢查(若是每隔100ms,所有key進行檢查,redis豈不是卡死)。所以,若是隻採用按期刪除策略,會致使不少key到時間沒有刪除。 因而,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key若是設置了過時時間那麼是否過時了?若是過時了此時就會刪除。

     (1)上面提到的隨機抽取的方式spa

一、隨機測試100個設置了過時時間的key
二、刪除全部發現的已過時的key
三、若刪除的key超過25個則重複步驟1

說明:這是一個基於機率的簡單算法,基本的假設是抽出的樣本可以表明整個key空間,redis持續清理過時的數據直至將要過時的key的百分比降到了25%如下。

另外每隔100ms檢測一次能夠手動修改這頻率,能夠找關於 hz 選項的說明。

注意:當REDIS運行在主從模式時,只有主結點纔會執行上述這兩種過時刪除策略,而後把刪除操做」del key」同步到從結點。

 

  四、採用按期刪除+惰性刪除就沒其餘問題了麼?

 

不是的,若是按期刪除沒刪除key。而後你也沒即時去請求key,也就是說惰性刪除也沒生效。這樣,redis的內存會愈來愈高。那麼就應該採用內存淘汰機制。

在redis.conf中有一行配置:# maxmemory-policy volatile-lru

該配置就是配內存淘汰策略的
    1)noeviction:當內存不足以容納新寫入數據時,新寫入操做會報錯。--不推薦。
    2)allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key。推薦使用。
    3)allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key。--不推薦。
    4)volatile-lru:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的key。這種狀況通常是把redis既當緩存,又作持久化存儲的時候才用。不推薦
    5)volatile-random:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個key。依然不推薦
    6)volatile-ttl:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的key優先移除。不推薦

 

總結與備忘

 

一、若是Redis中天天過時大量Key(好比幾千萬),那麼必須得考慮過時Key的清理:
    1)、增長Redis主動清理的頻率(經過調大hz參數);
    2)、手動清理過時Key,最簡單的方法是進行scan操做,scan操做會觸發第一種被動刪除,scan操做時候別忘了加count;

二、dbsize命令返回的Key數量,包含了過時Key;

三、randomkey命令返回的Key,不包含過時Key;

四、scan命令返回的Key,包含過時Key;

五、keys對應的Key數量等同於dbsize;

六、info命令返回的# Keyspace:db6:keys=1034937352,expires=994731489,avg_ttl=507838502
    1)、expires指的是設置了過時時間的Key數量;
    2)、avg_ttl指設置了過時時間的Key的平均過時時間(單位:毫秒);
相關文章
相關標籤/搜索