Was macht Redis, wenn der Speicher knapp wird?

111

Dies mag eine einfache Frage sein, aber es fällt mir schwer, die Antwort zu finden. Wie geht Redis 2.0 mit dem maximal zugewiesenen Speicher um? Wie entscheidet es, welche Daten entfernt oder welche Daten gespeichert werden sollen?

Cory
quelle

Antworten:

94

Wenn Sie die Funktionalität des virtuellen Speichers aktiviert haben (neu in Version 2.0 oder 2.2, glaube ich), beginnt Redis, die "nicht so häufig verwendeten" Daten auf der Festplatte zu speichern, wenn der Speicher knapp wird.

Wenn der virtuelle Speicher in Redis deaktiviert ist, scheint der virtuelle Speicher des Betriebssystems aufgebraucht zu sein (dh auszutauschen), und die Leistung sinkt enorm.

Jetzt können Sie Redis auch mit einem maxmemory-Parameter konfigurieren, der verhindert, dass Redis mehr Speicher verwendet (Standardeinstellung).

Neuere Versionen von Redis haben verschiedene Richtlinien, wenn maxmemory erreicht ist:

  • volatile-lru entfernt einen Schlüssel unter denjenigen mit einem abgelaufenen Satz und versucht, nicht kürzlich verwendete Schlüssel zu entfernen.
  • volatile-ttl entfernt einen Schlüssel unter denjenigen mit einem abgelaufenen Satz und versucht, Schlüssel mit kurzer verbleibender Lebensdauer zu entfernen.
  • volatile-random entfernt einen zufälligen Schlüssel unter denjenigen mit einem Ablaufsatz.
  • allkeys-lru wie volatile-lru, entfernt jedoch alle Arten von Schlüsseln, sowohl normale Schlüssel als auch Schlüssel mit einem Ablaufsatz.
  • allkeys-random wie volatile-random, entfernt jedoch alle Arten von Schlüsseln, sowohl normale Schlüssel als auch Schlüssel mit einem Ablaufsatz.

Wenn Sie eine Richtlinie auswählen, die nur Schlüssel mit einem EXPIRE-Satz entfernt, sieht es so aus, als würde das Programm die malloc () -Operation nur abbrechen, wenn Redis keinen Speicher mehr hat. Das heißt, wenn Sie versuchen, mehr Daten zu speichern, schlägt der Vorgang nur kläglich fehl.

Einige Links für weitere Informationen (da Sie nicht einfach mein Wort dafür nehmen sollten):

BMiner
quelle
8
Redis Virtual Memory ist jetzt veraltet. Siehe redis.io/topics/virtual-memory
cgaldiolo
19

Von redis.conf , Version 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
daniel__
quelle
3
Die Standardeinstellung maxmemory-policyin Redis 3.2 ist jetzt noeviction: raw.githubusercontent.com/antirez/redis/3.2/redis.conf
LoicAG
5

Update 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
oshaiken
quelle
4

Ich habe erst kürzlich angefangen, über Redis zu lesen, daher bin ich nicht positiv. Aber ich bin auf ein paar Leckerbissen gestoßen, die nützlich sein könnten.

Hier ist ein Ausschnitt aus http://antirez.com/post/redis-as-LRU-cache.html :

Eine andere Möglichkeit, Redis als Cache zu verwenden, ist die Anweisung maxmemory, mit der eine maximale Speichermenge angegeben werden kann. Wenn dem Server neue Daten hinzugefügt werden und das Speicherlimit bereits erreicht wurde, entfernt der Server einige alte Daten und löscht einen flüchtigen Schlüssel, dh einen Schlüssel, für den EXPIRE (Timeout) festgelegt ist, auch wenn der Schlüssel noch weit entfernt ist automatisch ablaufen.

Außerdem verfügt Redis 2.0 über einen VM-Modus, in dem alle Schlüssel in den Speicher passen müssen. Die Werte für die selten verwendeten Schlüssel können sich jedoch auf der Festplatte befinden:

Bporter
quelle
2

Wenn Sie sich fragen, was Redis (2.8) tatsächlich reagiert, wenn es das durch seine Konfiguration definierte Maximum erreicht, sieht es folgendermaßen aus:

$ 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'.
Lukáš Lánský
quelle
1

Ich hatte kürzlich eine Situation ohne freien Speicher und meine Anwendung kam zum Stillstand (Schreibvorgänge nicht möglich, Lesevorgänge waren möglich). Das Ausführen von PHP-Skripten wurde auf halbem Weg gestoppt und musste kill -9manuell ausgeführt werden (auch nachdem der Arbeitsspeicher vorhanden war) verfügbar gemacht).

Ich habe angenommen, dass ein Datenverlust (oder eine Dateninkonsistenz) aufgetreten ist, also habe ich eine durchgeführt flushdbund aus Sicherungen wiederhergestellt. Lektion gelernt? Backups sind dein Freund.

Adrian
quelle
-3

Redis ist kein Cache wie memcached. Standardmäßig (wobei der maxmemory-policyParameter auf gesetzt ist noeviction) werden alle Daten, die Sie in redis eingeben, nicht entfernt. Die einzige Ausnahme ist die Verwendung von EXPIRE.

Tobias P.
quelle
2
Was macht es also, wenn der Speicher knapp wird? Es werden nur neue Daten auf der Festplatte gespeichert, nicht im Speicher?
Cory
1
Dies ist (jetzt) ​​falsch. Redis verfügt über einen wichtigen Räumungsmechanismus mit mehreren verfügbaren Richtlinien: redis.io/topics/lru-cache
LoicAG
@LoicAG: Klingt für mich vollkommen richtig ... es sei denn, es gibt eine Enteignungsrichtlinie, Redis wird keinen Schlüssel räumen. Und das ist gut so: Ich kann es mir zum Beispiel nicht leisten, dass Redis die Schlüssel selbst loswird.
Michael
@Cory: Wenn eine Räumungsrichtlinie eingerichtet ist, werden vorhandene Schlüssel entfernt. Wenn Sie jedoch keine Räumungsrichtlinie festgelegt haben, sollte ein Fehler aufgrund von Speichermangel angezeigt werden.
Michael
@Michael Ich nehme an, es ist eine Frage der Terminologie: Es gibt immer eine Maxmemory-Richtlinie, und die Standardeinstellung ist in der Tat "noeviction"; Die Richtlinien "allkeys-lru" und "allkeys-random" entfernen jedoch Schlüssel aus der gesamten Gruppe, und die anderen ("volatile- *") entfernen Schlüssel aus der Teilmenge der Schlüssel, für die eine TTL definiert ist.
LoicAG