【redis】-- 緩存(redis作為緩存使用)



redis有兩種使用方式一是作為數據庫使用,二是作為緩存使用。

將redis作為緩存,當你新增數據時,讓它自動地回收舊數據是件很方便的事情。這個行為在開發者社區非常有名,因為它是流行的memcached系統的默認行為。而redis回收數據LRU是redis唯一支持的回收算法。

1.Maxmemory配置指令
maxmemory配置指令用於配置Redis存儲數據時指定限制的內存大小。通過redis.conf可以設置該指令,或者之后使用CONFIG SET命令來進行運行時配置。
例如為了配置內存限制為100mb,以下的指令可以放在redis.conf文件中。
maxmemory 100mb
設置maxmemory為0代表沒有內存限制。對於64位的系統這是個默認值,對於32位的系統默認內存限制為3GB。
當指定的內存限制大小達到時,需要選擇不同的行為,也就是策略。 Redis可以僅僅對命令返回錯誤,這將使得內存被使用得更多,或者回收一些舊的數據來使得添加數據時可以避免內存限制。

1.redis的回收策略

當maxmemory限制達到的時候Redis會使用的行為由 Redis的maxmemory-policy配置指令來進行配置。

以下的策略是可用的:

  • noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
  • allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
  • volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
  • allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
  • volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
  • volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。

如果沒有鍵滿足回收的前提條件的話,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。

選擇正確的回收策略是非常重要的,這取決於你的應用的訪問模式,不過你可以在運行時進行相關的策略調整,並且監控緩存命中率和沒命中的次數,通過RedisINFO命令輸出以便調優。

一般的經驗規則:

  • 使用allkeys-lru策略:當你希望你的請求符合一個冪定律分布,也就是說,你希望部分的子集元素將比其它其它元素被訪問的更多。如果你不確定選擇什么,這是個很好的選擇。.
  • 使用allkeys-random:如果你是循環訪問,所有的鍵被連續的掃描,或者你希望請求分布正常(所有元素被訪問的概率都差不多)。
  • 使用volatile-ttl:如果你想要通過創建緩存對象時設置TTL值,來決定哪些對象應該被過期。

allkeys-lru 和 volatile-random策略對於當你想要單一的實例實現緩存及持久化一些鍵時很有用。不過一般運行兩個實例是解決這個問題的更好方法。

為了鍵設置過期時間也是需要消耗內存的,所以使用allkeys-lru這種策略更加高效,因為沒有必要為鍵取設置過期時間當內存有壓力時。

redis的LRU回收算法

redis的回收算法並非真正的LRU算法,而是依據redis而改造過的算法。Redis為什么不使用真實的LRU實現是因為這需要太多的內存。不過近似的LRU算法對於應用而言應該是等價的。

LRU算法關於redis的具體實現:http://ifeve.com/redis-lru/

2.關於redis作為緩存時出現的擊穿,穿透,雪崩問題

1.擊穿

緩存擊穿:指的是在高並發的情況下(一定要是高並發情況,不然稱不上擊穿因為訪問量低時,擊穿不影響效率),在redis中設置的某一個或少量鍵因為超時被刪除,或被回收算法回收不存在時(總之就是鍵被刪除了),突然涌入大量的請求,請求被刪除的鍵鍵。此時大量的請求穿過redis緩存,之間服務數據庫,對數據庫造成壓力,導致數據庫效率降低,或崩潰的情況

圖片

要解決緩存擊穿問題,最主要是有多個線程同時服務一個數據造成了,問題的出現,所以要解決緩存擊穿問題最好是加鎖,讓同一時間只有一個數據來訪問從而緩解服務器的壓力。

redis實現分布式鎖:https://www.cnblogs.com/wf614/p/12275028.html

圖片

2.穿透

緩存穿透是指,大量請求請求數據庫中不存在,導致請求越過redis緩存直接訪問數據庫,通過大量的查詢操作,使數據庫服務器不能正常提供服務的情況。

要解決緩存穿透的問題,那么就要讓這些請求到達不了數據庫。所以可以在redis中存儲所有數據庫中的數據信息,讓redis阻擋這些請求。

可以使用布隆過濾器(bloom):

布隆過濾器的原理是,當一個元素被加入集合時,通過K個散列函數將這個元素映射成一個位數組中的K個點,把它們置為1。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:如果這些點有任何一個0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過濾器的基本思想。

所以,因為布隆過濾器存儲數據占用的空間很小,可以先把數據庫中的數據都存入布隆過濾器中,然后每次請求都先判斷它請求的數據是否存在,如果存在在提供服務,否則就不提供服務。

圖片

如上圖所說,因為布隆過濾器判斷條件是根據hash算出來的。所以有可能造成誤判,使請求不存在數據的請求到達數據庫,不過這樣的情況出現的可能性很小(>1%),所以可以使用布隆過濾器對數據進行,過濾。

不過布隆過濾器,不能刪除數據,當數據庫中某些數據被刪除時,布隆過濾器中其對應的鍵還存在,這是也會出現問題。此時可以選用其他和布隆過濾器類似但可以進行更改的過濾器,如布谷鳥過濾器。

3.緩存雪崩

緩存雪崩:是指在某一個時間段因為大量的key到達過期時間,被刪除,間接導致大量請求到達數據庫的情況。

緩存雪崩和緩存穿透類似都是,因為某種原因導致key失效。不過而在最大的區別是,它們失效key的數量不一樣。故不能通過解決穿透的方法來解決緩存雪崩。

要解決緩存雪崩問題,要分為兩種情況:

1.失效的數據是時點型數據(時點型數據是指到沒有數據的這些數據會失效,而我們不能預測新的數據是什么,即我們知道某些數據會在某個時間點被改變,而我們不知道數據被改變后的具體是什么,而被改變后存在redis緩存中的數據就成了無效數據的情況):這種情況我們可以在業務層添加計時器,到要過期的時間點時延時,在延時的時間里同步數據。

2.失效的不是時點數據而是熱數據:我們可以給這些數據設置隨機超時時間,使大量數據不在同時過期。

圖片


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM