限制內存大小
查看當前運行的 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
