Redis 內存大小限制與 key 刪除策略


限制內存大小

查看當前運行的 Redis 所使用的配置文件

windows

直接打開任務管理器查看

linux

ps -ef | grep redis

沒有配置內存大小或配置為 0 的話,32 位系統上默認為 3G,64 位系統上無限制。所以一般都要配置一下,單位是 bytes 字節。推薦設置為物理內存的 3/4,類似 HashMap 的負載因子。

 

取消持久化

先刪除原有的 dump.rdb,不然啟動后會加載

# 指定在多長時間內,有多少次更新操作,就將數據同步到數據文件,可以多個條件配合
# 滿足以下條件將會同步數據:
# 900秒(15分鍾)內有1個更改
# 300秒(5分鍾)內有10個更改
# 60秒內有10000個更改
# 可以把所有“save”行注釋掉,這樣就取消同步操作了
#save ""
#save 900 1
#save 300 10
#save 60 10000

# 如果用戶開啟了RDB快照功能,那么在 redis 持久化數據到磁盤時如果出現失敗,默認情況下,redis 會停止接受所有的寫請求
stop-writes-on-bgsave-error yes

# 指定存儲至本地數據庫時是否壓縮數據,默認為 yes,Redis 采用 LZF 壓縮,如果為了節省 CPU 時間,可以關閉該選項,但會導致數據庫文件變的巨大
rdbcompression yes

# 在存儲快照后,可以讓 redis 使用 CRC64 算法來進行數據校驗,這樣做會增加大約 10% 的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能
rdbchecksum yes

# 轉儲數據庫的文件名,默認值為 dump.rdb
dbfilename dump.rdb

# 工作目錄,指定本地數據庫存放目錄,文件名由上一個 dbfilename 配置項指定,這里只能指定一個目錄,不能指定文件名
dir ./

 

限制最大內存

windows 的 maxmemory-policy 策略可能會少一些

# 指定 Redis 最大內存限制,Redis 在啟動時會把數據加載到內存中,達到最大內存后,Redis 會先嘗試清除已到期或即將到期的 Key,移除規則可以通過 maxmemory-policy 來指定,當處理后,仍然到達最大內存,將無法再進行寫入操作,但仍然可以進行讀取操作
# Redis 新的 vm 機制,會把 Key 存放內存,Value 會存放在 swap 區
# maxmemory <bytes>
# 3GB = 3*1024*1024*1024=3221225472
maxmemory 3221225472

# 當內存使用達到最大值時,redis 使用的清除策略:
# LRU 表示最近最少使用,LFU 意味着最少使用
# volatile-lru -> 利用 LRU 算法移除設置過過期時間的 key
# allkeys-lru -> 利用 LRU 算法移除任何 key(常用)
# volatile-lfu -> 利用 LFU 算法移除設置過過期時間的 key
# allkeys-lfu -> 利用 LFU 算法移除任何 key
# volatile-random -> 移除設置過過期時間的隨機 key
# allkeys-random -> 移除隨機 key
# volatile-ttl -> 移除即將過期的 key(minor TTL)
# noeviction -> 不移除任何 key,只是返回一個寫錯誤(默認)
maxmemory-policy noeviction

# LRU,LFU 和最小 TTL 算法不是精確的算法,而是近似算法(為了節省內存),默認 Redis 將檢查 5 個鍵並選擇最近使用的鍵,可以配置指令更改樣本大小獲得速度或精度。默認值 5 會產生足夠好的結果,10 非常接近真實的 LRU,但耗 CPU,3 更快,但不是很准確。
maxmemory-samples 5

 

重啟服務

windows

net stop redis 
net start redis

linux

systemctl restart redis

 

命令行方式修改

# 設置 100M
config set maxmemory 104857600
config set maxmemory-policy allkeys-lru
# 查看
config get maxmemory
# maxmemory_human:總共,used_memory_human:已使用
info memory
# 查看所有配置
config get *

 

過期刪除策略

數據刪除策略的目標

在內存占用與 CPU 占用之間尋找一種平衡,顧此失彼都會造成整體 Redis 性能的下降,甚至發服務器宕機或內存泄露

 

時效性存儲結構

主要就是操作 expires 空間

 

數據刪除策略

定時刪除

  • 創建一個定時器,當 key 設置有 過期時間,且過期時間到達時,由定時器任務立即執行對鍵的刪除操作
  • 優點:節約內存,到時就刪除,快速釋放掉不必要的內存占用
  • 缺點:CPU 壓力很大,無論 CPU 此時負載量多高,均占用 CPU,會影響 Redis 服務器響應時間和指令吞吐量
  • 總結:用處理器性能換取存儲空間(拿時間換空間)

惰性刪除

  • 數據到達過期時間,不做處理。等下次訪問該數據時。如果未過期,返回數據。發現已過期,刪除,返回不存在
  • 優點:節約 CPU 性能,發現必須刪除的時候才刪除
  • 缺點:內存壓力很大,出現長期占用內存的數據
  • 總結:用存儲空間換取處理器性能(拿空間換時間)

定期刪除

Redis 啟動服務器初始化時,讀取配置 server.hz 的值,默認為 10

每秒鍾執行 server.hz 次 serverCron() -> databasesCron() -> activeExpireCycle()

activeExpireCycle() 對每個 expires[*] 逐一進行檢測,每次執行 250ms/server.hz

對某個 expires[*] 檢測時,隨機挑選 W 個 key 檢測

  • 如果 key 超時,刪除 key
  • 如果一輪中刪除的 key 的數量 > W*25%,循環該過程
  • 如果一輪中刪除的 key 的數量 ≤ W*25%,檢查下一個 expires[*],0-15 循環
  • W 取值 = ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 屬性值

參數 current_db 用於記錄 activeExpireCycle() 進入哪個 expires[*] 執行

如果 activeExpireCycle() 執行時間到期,下次從 current db 繼續向下執行

周期性輪詢 Redis 庫中的時效性數據,采用隨機抽取的策略,利用過期數據占比的方式控制刪除頻度

  • 特點 1:CPU 性能占用設置有峰值,檢測頻度可自定義設置
  • 特點 2:內存壓力不是很大,長期占用內存的冷數據會被持續清理

總結:周期性抽查存儲空間(隨機抽查,重點抽查)

刪除策略比對

定時刪除:節約內存、無占用。不分時段占用 CPU 資源,頻度高。拿時間換空間

惰性刪除:內存占用嚴重、延時執行,CPU 利用率高、拿空間換時間

定期刪除:內存定期隨機清理。每秒花費固定的 CPU 資源維護內存。隨機抽查,重點抽查。CPU 和內存的折中方案

Redis 默認使用定期和惰性兩種。

 

數據逐出策略

Redis 使用內存存儲數據,在執行每一個命令前,會調用 freeMemorylfNeeded() 檢測內存是否充足。

如果內存不滿足新加入數據的最低存儲要求,Redis 要臨時刪除些數據為當前指令清理存儲空間。

清理數據的策略稱為逐出算法。

逐出數據的過程不是 100% 能夠清理出足夠的可使用的內存空間,如果不成功則反復執行。

當對所有數據嘗試完畢后,如果不能達到內存清理的要求,將出現錯誤信息。

影響數據逐出的相關配置

# 最大可使用內存,占用物理內存的比例,默認值為 0,標不限制。生產環境中根據需求設定,通常設置在 50% 以上
maxmemory

# 每次選取待刪除數據的個數,選取數據時並不會全庫掃描,導致嚴重的性能消耗,降低讀寫性能。因此采用隨機獲取數據的方式作為待檢測刪除數據
maxmemory-samples

# 刪除策略,達到最大內存后的,對被挑選出來的數據進行刪除的策略
maxme mory-policy

# 逐出策略
maxmemory-policy volatile-lru

LRU(Least Recently Used):一個時間段里最長時間沒有被使用的數據

LFU(Least Frequently Used):一個時間段里使用次數最少的數據

檢測易失數據(可能會過期的數據集 server.db[i].expires)

  • volatile-lru:挑選最近最少使用的數據淘汰
  • volatile lfu:挑選最近使用次數最少的數據淘汰
  • volatile-ttl:挑選將要過期的數據淘汰
  • volatile-random:任意選擇數據淘汰

檢測全庫數據(所有數據集server.db[i].dict)

  • allkeys-lru:挑選最近最少使用的數據淘汰
  • allkeys-lfu:挑選最近使用次數最少的數據淘汰
  • allkeys-random:任意選擇數據淘汰

放棄數據驅逐

  • no-enviction(驅逐):禁止驅逐數據(Redis4.0 中默認策略),會引發錯誤 OOM(Out Of Memory)

建議設置 volatile-lru

數據逐出策略配置依據可以使用 INFO 命令輸出監控信息,查詢緩存 hit 和 miss 的次數,根據業務需求調優 Redis 配置

 


http://www.redis.cn/topics/config.html

http://www.redis.cn/topics/persistence.html

https://redis.io/commands/expire

https://redis.io/topics/lru-cache

https://tech.meituan.com/2017/03/17/cache-about.html


免責聲明!

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



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