Redis는 메모리가 부족할 때 무엇을합니까?


111

이것은 쉬운 질문 일지 모르지만 답을 찾는 데 어려움을 겪고 있습니다. Redis 2.0은 할당 된 최대 메모리 부족을 어떻게 처리합니까? 제거 할 데이터 또는 메모리에 보관할 데이터를 어떻게 결정합니까?


답변:


94

가상 메모리 기능이 켜져있는 경우 (버전 2.0 또는 2.2의 새로운 기능) Redis는 메모리가 부족할 때 "그다지 자주 사용되지 않는"데이터를 디스크에 저장하기 시작합니다.

Redis의 가상 메모리가 비활성화되면 운영 체제의 가상 메모리가 소모되기 시작하는 것처럼 나타나고 (예 : 스왑) 성능이 엄청나게 저하됩니다.

이제 maxmemory 매개 변수로 Redis를 구성하여 Redis가 더 이상 메모리 (기본값)를 사용하지 못하도록 할 수도 있습니다.

최신 버전의 Redis에는 maxmemory에 도달하면 다양한 정책이 있습니다.

  • volatile-lru는 만료가 설정된 키 중에서 최근에 사용하지 않은 키를 제거하려고합니다.
  • volatile-ttl은 만료가 설정된 키 중에서 키를 제거하고 남은 수명이 짧은 키를 제거하려고합니다.
  • volatile-random은 만료가 설정된 키 중에서 임의의 키를 제거합니다.
  • allkeys-lru는 volatile-lru와 비슷하지만 모든 종류의 키, 일반 키 또는 만료 세트가있는 키를 모두 제거합니다.
  • allkeys-random은 volatile-random과 비슷하지만 모든 종류의 키, 일반 키와 만료 세트가있는 키를 모두 제거합니다.

EXPIRE가 설정된 키만 제거하는 정책을 선택하면 Redis가 메모리가 부족할 때 프로그램이 malloc () 작업을 중단하는 것처럼 보입니다. 즉, 더 많은 데이터를 저장하려고하면 작업이 비참하게 실패합니다.

더 많은 정보를 얻을 수있는 몇 가지 링크 (내 말을 믿어서는 안되기 때문에) :


8
Redis 가상 메모리는 이제 더 이상 사용되지 않습니다. 참조 redis.io/topics/virtual-memory
cgaldiolo

19

에서 redis.conf , 버전 2.8

# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU cache, or to set
# a hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory <bytes>

# 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 volatile-lru

3
maxmemory-policyRedis 3.2 의 기본값 은 noeviction다음과 같습니다. raw.githubusercontent.com/antirez/redis/3.2/redis.conf
LoicAG

5

redis 4.0 업데이트

127.0.0.1:6379> MEMORY HELP
1) "MEMORY DOCTOR                        - Outputs memory problems report"
2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
3) "MEMORY STATS                         - Show memory usage details"
4) "MEMORY PURGE                         - Ask the allocator to release memory"
5) "MEMORY MALLOC-STATS                  - Show allocator internal stats"

/usr/local/etc/redis.conf

############################## MEMORY MANAGEMENT ################################

# Set a memory usage limit to the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU or LFU cache, or to
# set a hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory <bytes>

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones 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 evict anything, just return an error on write operations.
#
# LRU means Least Recently Used
# LFU means Least Frequently Used
#
# Both LRU, LFU and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# 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, LFU 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 more CPU. 3 is faster but not very accurate.
#
# maxmemory-samples 5

4

최근에 Redis에 대해 읽기 시작했기 때문에 긍정적이지 않습니다. 하지만 유용한 정보를 몇 가지 발견했습니다.

다음은 http://antirez.com/post/redis-as-LRU-cache.html 의 스 니펫입니다 .

Redis를 캐시로 사용하는 또 다른 방법은 사용할 최대 메모리 양을 지정할 수있는 기능인 maxmemory 지시문입니다. 새 데이터가 서버에 추가되고 메모리 제한에 이미 도달 한 경우 서버는 키가 아직 멀더라도 휘발성 키, 즉 EXPIRE (시간 초과)가 설정된 키를 삭제하는 일부 오래된 데이터를 제거합니다. 자동으로 만료됩니다.

또한 Redis 2.0에는 모든 키가 메모리에 맞아야하는 VM 모드가 있지만 거의 사용되지 않는 키의 값은 디스크에있을 수 있습니다.


2

Redis (2.8)가 구성에 정의 된 최대 값에 도달했을 때 실제로 어떤 반응을 보이는지 궁금하다면 다음과 같습니다.

$ redis-cli
127.0.0.1:6379> GET 5
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
127.0.0.1:6379> SET 5 a
(error) OOM command not allowed when used memory > 'maxmemory'.

1

나는 최근에 메모리가 부족한 상황을 경험하고 애플리케이션이 중단 (쓰기 불가능, 읽기 가능)하여 PHP 스크립트 실행이 중간에 중단되고 kill -9수동으로 'd'해야했습니다. 사용 가능).

데이터 손실 (또는 데이터 불일치)이 발생했다고 가정 flushdb하고 백업에서 복원했습니다. 교훈을 얻었습니까? 백업은 당신의 친구입니다.


-3

Redis는 memcached와 같은 캐시가 아닙니다. 기본적으로 ( maxmemory-policy매개 변수가로 설정된 경우 noeviction) redis에 넣은 모든 데이터는 제거되지 않으며 유일한 예외는 EXPIRE를 사용하는 것입니다.


2
그렇다면 메모리가 부족하면 무엇을합니까? 메모리가 아닌 디스크에 새 데이터를 저장합니까?
Cory

1
이다 (지금은) 잘못된, 레디 스 여러 가능한 정책과 키 퇴거 메커니즘이 있습니다 redis.io/topics/lru-cache
LoicAG

@LoicAG : 나에게 완벽하게 맞는 것 같네요 ... 만료 정책이 없으면 Redis는 키를 제거하지 않습니다. 그리고 그것은 좋습니다. 예를 들어 저는 Redis가 스스로 키를 제거하도록 할 수 없습니다.
Michael

@Cory : 퇴거 정책이 설정되어있는 경우 기존 키를 제거합니다. 그러나 제거 정책을 설정하지 않은 경우 메모리 부족 오류를 수신해야합니다.
Michael

@Michael 저는 그것이 용어의 문제라고 생각합니다 : 항상 maxmemory-policy가 제자리에 있고 기본값은 실제로 "noeviction"입니다. 그러나 "allkeys-lru"및 "allkeys-random"정책은 전체 집합에서 키를 제거하고 다른 ( "volatile- *") 정책은 TTL이 정의 된 키 하위 집합에서 키를 제거합니다.
LoicAG
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.