[轉帖]redis中的maxmemory

济南小老虎發表於2024-06-20

前言

  • 當redis中的儲存資料的容量達到最大時,若果我們再往裡面儲存資料,redis在預設的配置下會丟擲異常,那麼當mem_used記憶體已經超過maxmemory,我們採取的措施是什麼哪?

清理策略

  • 1.volatile-lru:從設定了過期時間的資料集中,選擇最近最久未使用的資料釋放。
  • 2.allkeys-lru:從資料集中(包括設定過期時間以及未設定過期時間的資料集中),選擇最近最久未使用的資料釋放。
  • 3.volatile-random:從設定了過期時間的資料集中,隨機選擇一個資料進行釋放。
  • 4.allkeys-random:從資料集中(包括了設定過期時間以及未設定過期時間)隨機選擇一個資料進行入釋放。
  • 5.volatile-ttl:從設定了過期時間的資料集中,選擇馬上就要過期的資料進行釋放操作。
  • 6.noeviction:不刪除任意資料(但redis還會根據引用計數器進行釋放呦~),這時如果記憶體不夠時,會直接返回錯誤。
預設配置是noeviction

過程解析

  • 當mem_used記憶體已經超過maxmemory的設定,對於所有的讀寫請求,都會觸發redis.c/freeMemoryIfNeeded(void)函式以清理超出的記憶體。注意這個清理過程是阻塞的,直到清理出足夠的記憶體空間。所以如果在達到maxmemory並且呼叫方還在不斷寫入的情況下,可能會反覆觸發主動清理策略,導致請求會有一定的延遲。

redis.conf的預設配置

# Redis calls an internal function to perform many background tasks, like 
# closing connections of clients in timeout, purging expired keys that are 
# never requested, and so forth. 
# 
# Not all tasks are performed with the same frequency, but Redis checks for 
# tasks to perform according to the specified "hz" value. 
# 
# By default "hz" is set to 10. Raising the value will use more CPU when 
# Redis is idle, but at the same time will make Redis more responsive when 
# there are many keys expiring at the same time, and timeouts may be 
# handled with more precision. 
# 
# The range is between 1 and 500, however a value over 100 is usually not 
# a good idea. Most users should use the default of 10 and raise this up to 
# 100 only in environments where very low latency is required. 
hz 10 

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
#
# Note: with any of the above policies, Redis will return an error on write
# operations, when there are no suitable keys for eviction.
#
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# The default is:
#
maxmemory-policy noeviction

# LRU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. For default Redis will check five keys and pick the one that was
# used less recently, you can change the sample size using the following
# configuration directive.
#
# The default of 5 produces good enough results. 10 Approximates very closely
# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
#
maxmemory-samples 5

    小結

    • maxmemory-samples在redis-3.0.0中的預設配置為5,如果增加,會提高LRU或TTL的精準度,redis作者測試的結果是當這個配置為10時已經非常接近全量LRU的精準度了,並且增加maxmemory-samples會導致在主動清理時消耗更多的CPU時間。
    </article>
    

    相關文章