亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis內存滿了然后去優化

發布時間:2022-03-15 15:40:12 來源:億速云 閱讀:215 作者:iii 欄目:關系型數據庫

這篇文章主要介紹“Redis內存滿了然后去優化”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Redis內存滿了然后去優化”文章能幫助大家解決問題。

Redis內存滿了然后去優化

Redis內存滿了怎么辦?怎么優化內存?

MySQL里有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據

redis內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。

Redis主要消耗什么物理資源?

內存。

Redis的內存用完了會發生什么?

如果達到設置的上限,Redis的寫命令會返回錯誤信息(但是讀命令還可以正常返回。)或者你可以配置內存淘汰機制,當Redis達到內存上限時會沖刷掉舊的內容。

談談緩存數據的淘汰機制

Redis 緩存有哪些淘汰策略?

  • 不進行數據淘汰的策略,只有 noeviction 這一種。

會進行淘汰的 7 種策略,我們可以再進一步根據淘汰候選數據集的范圍把它們分成兩類:

  • 在設置了過期時間的數據中進行淘汰,包括 volatile-random、volatile-ttl、volatile-lru、volatile-lfu四種。

  • 在所有數據范圍內進行淘汰,包括 allkeys-lru、allkeys-random、allkeys-lfu三種。

策略規則
volatile-ttl在篩選時,會針對設置了過期時間的鍵值對,根據過期時間的先后進行刪除,越早過期的越先被刪除。
volatile-random在設置了過期時間的鍵值對中,進行隨機刪除。
volatile-lru使用 LRU 算法篩選設置了過期時間的鍵值對
volatile-lfu使用 LFU 算法選擇設置了過期時間的鍵值對
策略規則
allkeys-random從所有鍵值對中隨機選擇并刪除數據;
allkeys-lru使用 LRU 算法在所有數據中進行篩選
vallkeys-lfu使用 LFU 算法在所有數據中進行篩選

談談LRU算法

是按照最近最少使用的原則來篩選數據,最不常用的數據會被篩選出來,而最近頻繁使用的數據會留在緩存中。

那具體是怎么篩選的呢?LRU 會把所有的數據組織成一個鏈表,鏈表的頭和尾分別表示 MRU 端和 LRU 端,分別代表最近最常使用的數據和最近最不常用的數據。
Redis內存滿了然后去優化
LRU 算法背后的想法非常樸素:它認為剛剛被訪問的數據,肯定還會被再次訪問,所以就把它放在 MRU 端;長久不訪問的數據,肯定就不會再被訪問了,所以就讓它逐漸后移到 LRU 端,在緩存滿時,就優先刪除它。

問題:LRU 算法在實際實現時,需要用鏈表管理所有的緩存數據,這會帶來額外的空間開銷。而且,當有數據被訪問時,需要在鏈表上把該數據移動到 MRU 端,如果有大量數據被訪問,就會帶來很多鏈表移動操作,會很耗時,進而會降低 Redis 緩存性能。

解決
在 Redis 中,LRU 算法被做了簡化,以減輕數據淘汰對緩存性能的影響。具體來說,Redis 默認會記錄每個數據的最近一次訪問的時間戳(由鍵值對數據結構 RedisObject 中的 lru 字段記錄)。然后,Redis 在決定淘汰的數據時,第一次會隨機選出 N 個數據,把它們作為一個候選集合。接下來,Redis 會比較這 N 個數據的 lru 字段,把 lru 字段值最小的數據從緩存中淘汰出去。
當需要再次淘汰數據時,Redis 需要挑選數據進入第一次淘汰時創建的候選集合。這兒的挑選標準是:能進入候選集合的數據的 lru 字段值必須小于候選集合中最小的 lru 值。當有新數據進入候選數據集后,如果候選數據集中的數據個數達到了 maxmemory-samples,Redis 就把候選數據集中 lru 字段值最小的數據淘汰出去。

使用建議

  • 優先使用 allkeys-lru 策略。這樣,可以充分利用 LRU 這一經典緩存算法的優勢,把最近最常訪問的數據留在緩存中,提升應用的訪問性能。如果你的業務數據中有明顯的冷熱數據區分,我建議你使用 allkeys-lru 策略。

  • 如果業務應用中的數據訪問頻率相差不大,沒有明顯的冷熱數據區分,建議使用 allkeys-random 策略,隨機選擇淘汰的數據就行。

  • 如果你的業務中有置頂的需求,比如置頂新聞、置頂視頻,那么,可以使用 volatile-lru 策略,同時不給這些置頂數據設置過期時間。這樣一來,這些需要置頂的數據一直不會被刪除,而其他數據會在過期時根據 LRU 規則進行篩選。

如何處理被淘汰的數據?

一旦被淘汰的數據選定后,如果這個數據是干凈數據,那么我們就直接刪除;如果這個數據是臟數據,我們需要把它寫回數據庫。

那怎么判斷一個數據到底是干凈的還是臟的呢?

  • 干凈數據和臟數據的區別就在于,和最初從后端數據庫里讀取時的值相比,有沒有被修改過。干凈數據一直沒有被修改,所以后端數據庫里的數據也是最新值。在替換時,它可以被直接刪除。

  • 而臟數據就是曾經被修改過的,已經和后端數據庫中保存的數據不一致了。此時,如果不把臟數據寫回到數據庫中,這個數據的最新值就丟失了,就會影響應用的正常使用。

即使淘汰的數據是臟數據,Redis 也不會把它們寫回數據庫。所以,我們在使用 Redis 緩存時,如果數據被修改了,需要在數據修改時就將它寫回數據庫。否則,這個臟數據被淘汰時,會被 Redis 刪除,而數據庫里也沒有最新的數據了。

Redis怎么優化內存?

1、控制key的數量:當使用Redis存儲大量數據時,通常會存在大量鍵,過多的鍵同樣會消耗大量內存。Redis本質是一個數據結構服務器,它為我們提供多種數據結構,如hash,list,set,zset 等結構。使用Redis時不要進入一個誤區,大量使用get/set這樣的API,把Redis當成Memcached使用。對于存儲相同的數據內容利用Redis的數據結構降低外層鍵的數量,也可以節省大量內存。
2、縮減鍵值對象,降低Redis內存使用最直接的方式就是縮減鍵(key)和值(value)的長度。

  • key長度:如在設計鍵時,在完整描述業務情況下,鍵值越短越好。

  • value長度:值對象縮減比較復雜,常見需求是把業務對象序列化成二進制數組放入Redis。首先應該在業務上精簡業務對象,去掉不必要的屬性避免存儲無效數據。其次在序列化工具選擇上,應該選擇更高效的序列化工具來降低字節數組大小。

3、編碼優化。Redis對外提供了string,list,hash,set,zet等類型,但是Redis內部針對不同類型存在編碼的概念,所謂編碼就是具體使用哪種底層數據結構來實現。編碼不同將直接影響數據的內存占用和讀寫效率。


  • 1、redisObject對象
    Redis內存滿了然后去優化

type字段
利用集合類型數據,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。盡可能使用散列表(hashes),散列表(是說散列表里面存儲的數少)使用的內存非常小,所以你應該盡可能的將你的數據模型抽象到一個散列表里面。比如你的web系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的所有信息存儲到一張散列表里面。

encoding字段:
采用不同的編碼實現內存占用存在明顯差異

lru字段:
開發提示:可以使用scan + object idletime 命令批量查詢哪些鍵長時間未被訪問,找出長時間不訪問的鍵進行清理降低內存占用。

refcount字段:
當對象為整數且范圍在[0-9999]時,Redis可以使用共享對象的方式來節省內存。

ptr字段 :
開發提示:高并發寫入場景中,在條件允許的情況下建議字符串長度控制在39字節以內,減少創建redisObject內存分配次數從而提高性能。


  • 2、縮減鍵值對象
    降低Redis內存使用最直接的方式就是縮減鍵(key)和值(value)的長度。
    可以使用通用壓縮算法壓縮json,xml后再存入Redis,從而降低內存占用


  • 3、共享對象池
    對象共享池指Redis內部維護[0-9999]的整數對象池。創建大量的整數類型redisObject存在內存開銷,每個redisObject內部結構至少占16字節,甚至超過了整數自身空間消耗。所以Redis內存維護一個[0-9999]的整數對象池,用于節約內存。 除了整數值對象,其他類型如list,hash,set,zset內部元素也可以使用整數對象池。因此開發中在滿足需求的前提下,盡量使用整數對象以節省內存。
    當設置maxmemory并啟用LRU相關淘汰策略如:volatile-lru,allkeys-lru時,Redis禁止使用共享對象池。

為什么開啟maxmemory和LRU淘汰策略后對象池無效?
LRU算法需要獲取對象最后被訪問時間,以便淘汰最長未訪問數據,每個對象最后訪問時間存儲在redisObject對象的lru字段。對象共享意味著多個引用共享同一個redisObject,這時lru字段也會被共享,導致無法獲取每個對象的最后訪問時間。如果沒有設置maxmemory,直到內存被用盡Redis也不會觸發內存回收,所以共享對象池可以正常工作。
綜上所述,共享對象池與maxmemory+LRU策略沖突,使用時需要注意。

為什么只有整數對象池?
首先整數對象池復用的幾率最大,其次對象共享的一個關鍵操作就是判斷相等性,Redis之所以只有整數對象池,是因為整數比較算法時間復雜度為O(1),只保留一萬個整數為了防止對象池浪費。如果是字符串判斷相等性,時間復雜度變為O(n),特別是長字符串更消耗性能(浮點數在Redis內部使用字符串存儲)。對于更復雜的數據結構如hash,list等,相等性判斷需要O(n2)。對于單線程的Redis來說,這樣的開銷顯然不合理,因此Redis只保留整數共享對象池。


  • 4、字符串優化
    Redis沒有采用原生C語言的字符串類型而是自己實現了字符串結構,內部簡單動態字符串,簡稱SDS。

字符串結構

  • 特點:
    O(1)時間復雜度獲取:字符串長度,已用長度,未用長度。
    可用于保存字節數組,支持安全的二進制數據存儲。
    內部實現空間預分配機制,降低內存再分配次數。
    惰性刪除機制,字符串縮減后的空間不釋放,作為預分配空間保留。

預分配機制

  • 開發提示:盡量減少字符串頻繁修改操作如append,setrange, 改為直接使用set修改字符串,降低預分配帶來的內存浪費和內存碎片化。

字符串重構:基于hash類型的二級編碼方式。

  • 二級編碼怎么用?
    二級編碼方法中采用的 ID 長度是有講究的。
    涉及到一個問題–Hash 類型底層結構小于設定值時使用壓縮列表,大于設定值時使用哈希表。
    一旦從壓縮列表轉為了哈希表,Hash 類型會一直用哈希表進行保存,而不會再轉回壓縮列表。
    在節省內存空間方面,哈希表就沒有壓縮列表那么高效。為能充分使用壓縮列表的精簡內存布局,一般要控制保存在 Hash 中的元素個數。


  • 5.編碼優化
    使用壓縮列表ziplist編碼的hash類型依然比使用hashtable編碼的集合節省大量內存。


  • 6.控制key的數量
    開發提示:使用ziplist+hash優化keys后,如果想使用超時刪除功能,開發人員可以存儲每個對象寫入的時間,再通過定時任務使用hscan命令掃描數據,找出hash內超時的數據項刪除即可。


當Redis內存不足時,首先考慮的問題不是加機器做水平擴展,應該先嘗試做內存優化。當遇到瓶頸時,再去考慮水平擴展。即使對于集群化方案,垂直層面優化也同樣重要,避免不必要的資源浪費和集群化后的管理成本。

關于“Redis內存滿了然后去優化”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿巴嘎旗| 静宁县| 和平区| 麦盖提县| 马公市| 广平县| 竹北市| 西吉县| 勐海县| 松原市| 子洲县| 金门县| 甘谷县| 威海市| 高雄县| 和林格尔县| 农安县| 新密市| 兴安县| 丘北县| 鲜城| 泰州市| 湖北省| 华坪县| 南木林县| 吐鲁番市| 玉门市| 中山市| 潼南县| 凭祥市| 烟台市| 清苑县| 哈巴河县| 色达县| 南平市| 慈溪市| 玉田县| 曲水县| 吉林省| 香格里拉县| 修水县|