Redis是一種基於內存的數據存儲,內存的大小決定Redis的容量,在Redis的使用過程中,可以使用一些技巧,減少內存的消耗,增大Redis的可用容量
Redis的內存管理:
- 當key被移除時,Redis不會總是釋放(返回)內存到操作系統。例如,如果用5GB的數據填充一個實例,然後刪除2GB的數據,那麼常駐集大小(也稱爲RSS,它是進程消耗的內存頁數)可能仍然在5GB左右,即使Redis會聲稱用戶內存在3GB左右。發生這種情況的原因是底層分配器無法輕鬆釋放內存。例如,通常大多數刪除的鍵與仍然存在的其他鍵在同一頁中分配。
- 前一點意味着需要根據峯值內存使用量來配置內存。如果工作負載不時需要10GB,即使大多數情況下5GB可以做到,也需要爲10GB做準備。
- 不過,分配器是智能的,能夠重用空閒的內存塊,因此在釋放了2GB的5GB數據集之後,當再次開始添加更多key直到達到2G時,將看到RSS(常駐集大小)保持穩定,而不會增加更多。分配器基本上是試圖重用先前(邏輯上)釋放的2GB內存。
- 由於這些原因,當內存使用率在峯值時遠大於當前使用的內存時,碎片率是不穩定的。
一、Redis內存設置
1、maxmemory <bytes> 最大內存限制
設置內存使用限制, 當Redis到達內存使用限制時,將根據淘汰策略刪除Key,如果Redis不能刪除Key得到足夠的內存,將拋出錯誤。默認情況下該配置不設置,使用OS內存。
2、maxmemory-policy noeviction Redis淘汰機制
策略 | 描述 |
---|---|
volatile-lru | 用近似LRU策略從Expire key集合中刪除key |
allkeys-lru | 用近似LRU策略從全部 key集合中刪除key |
volatile-random | 從Expire key集合中隨機刪除key |
allkeys-random | 從全部 key集合中隨機刪除key |
volatile-ttl | 刪除最近過期時間的key(更小TTL) |
noeviction | 不選擇淘汰key 返回一個錯誤 |
3、maxmemory-samples 5 精度設置
LRU、LFU和最小TTL算法不是精確算法,而是近似算法(爲了節省內存),因此可以調整它的速度或精度。默認情況下,Redis將檢查五個key並選擇最近使用較少的鍵,可以使用配置指令更改樣本大小。
默認值5產生足夠好的結果。10非常接近真實的LRU,但需要更多的CPU。3更快,但不太準確。
二、儘可能的使用Hash
Redis對內部數據類型的存儲做了優化,當使用Hash、List、Set<Integer>和Zset時,Redis提供了一些配置參數,在這些條件下,Redis會自動爲這些數據類型進行編碼以縮小內存的使用。
數據類型 | 配置 | 描述 |
---|---|---|
Hash | hash-max-ziplist-entries 512 | 當哈希有少量的條目,並且最大的條目不超過給定的閾值時,使用內存高效的數據結構對其進行編碼。 |
hash-max-ziplist-value 64(bytes) | ||
List | list-max-ziplist-size -2 |
List可以通過該配置進行編碼,當是負數時,代表指定的閥值是List的內存大小,默認是-2 # -5: max size: 64 Kb <-- not recommended for normal workloads 當配置是正數是,代表List元素的個數 |
list-compress-depth 0 |
0 禁止所有的List壓縮 1 深度爲1意味着不壓縮頭和尾:So: [head]->node->node->...->node->[tail] 2 深度爲2 [head]->[next]->node->node->...->node->[prev]->[tail] 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] |
|
set | set-max-intset-entries 512 | 當集合全部是正數元素時,會對集合進行特殊編碼 |
Zset | zset-max-ziplist-entries 128 | 同Hash |
zset-max-ziplist-value 64 | 同Hash |