web-dev-qa-db-fra.com

Comment Redis fonctionne-t-il lorsque RAM commence à se remplir?

Je pourrais être totalement hors tension, mais ma compréhension du fonctionnement des magasins de cache avant de commencer à ajouter des fonctionnalités de persistance, est que les éléments expireraient en fonction de leur ttl. Et si le magasin commençait à remplir la RAM disponible, ils auraient chacun leurs algorithmes pour expirer les clés les moins "importantes" du magasin.

Maintenant, je lis que Redis a des fonctionnalités de persistance. Mais vous pouvez les désactiver. En supposant que vous désactivez la persistance, que se passe-t-il lorsque RAM se remplit? Comment Redis décide-t-il de l'expiration?

Je m'attends à avoir beaucoup de données sans TTL et je veux m'assurer qu'il est sûr de laisser Redis déterminer ce qui va expirer.

33
joedevon

Je ne pense pas que la question soit liée à la gestion de la mémoire virtuelle, mais plutôt à l'expiration des éléments dans Redis, qui est un sujet totalement différent.

Contrairement à memcached, Redis n'est pas seulement un cache. L'utilisateur est donc censé choisir la politique d'expulsion des articles en utilisant divers mécanismes. Vous pouvez expulser tous vos objets, ou seulement une partie d'entre eux.

La politique générale doit être sélectionnée dans le fichier de configuration avec les paramètres maxmemory et maxmemory-policy, décrits ci-dessous:

# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys with an
# EXPIRE set. It will try to start freeing keys that are going to expire
# in little time and preserve keys with a longer time to live.
# Redis will also try to remove objects from free lists if possible.
#
# If all this fails, Redis will start to reply with errors to commands
# that will use more memory, like SET, LPUSH, and so on, and will continue
# to reply to most read-only commands like GET.
#
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
# 'state' server or cache, not as a real DB. When Redis is used as a real
# database the memory usage will grow over the weeks, it will be obvious if
# it is going to use too much memory in the long run, and you'll have the time
# to upgrade. With maxmemory after the limit is reached you'll start to get
# errors for write operations, and this may even lead to DB inconsistency.
#
maxmemory <bytes>

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached? You can select among five behavior:
#
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key accordingly 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 all the kind of policies, Redis will return an error on write
#       operations, when there are not suitable keys for eviction.
#
#       At the date of writing this 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

# LRU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can select as well the sample
# size to check. For instance for default Redis will check three keys and
# pick the one that was used less recently, you can change the sample size
# using the following configuration directive.
#
maxmemory-samples 3

L'expiration de chaque élément peut ensuite être définie à l'aide des commandes suivantes: EXPIRE EXPIREAT Le par la propriété d'expiration de l'élément est utile avec les politiques volatiles *. L'expiration peut également être supprimée à l'aide de PERSIST .

La propriété d'expiration ajoute une légère surcharge de mémoire, elle ne doit donc être utilisée qu'en cas de besoin.

Enfin, il convient de mentionner qu'une partie d'un objet ne peut pas expirer, uniquement l'objet entier lui-même. Par exemple, une liste entière ou un ensemble correspondant à une clé peut expirer, mais pas une liste individuelle ou des éléments d'ensemble.

43
Didier Spezia

Didier a raison d'indiquer comment procéder. Juste en indiquant quelques éléments supplémentaires (dont l'un semble avoir été omis de son poste):

  1. Spécifiez la taille de mémoire maximale pour occuper la majeure partie de la mémoire disponible sur ce nœud (en laisser une partie pour le système d'exploitation et d'autres processus et une partie du tampon). Cela garantira que le contenu n'est jamais paginé et que les opérations sont donc RAPIDES.
    1. Si vous ne définissez pas de TTL/clés expirantes via l'application, il est important que vous utilisiez l'approche "allkeys-lru". Sinon, Redis n'expirera rien (car aucune des clés n'est volatile), et vous commencerez à obtenir des erreurs une fois que toute la mémoire sera utilisée - fondamentalement, vous ne pourrez plus effectuer d'opérations définies.
    2. Lorsque vous utilisez le LRU pour retirer des clés, il est important de définir le paramètre suivant:

maxmemory-samples 10

Il s'agit du nombre d'échantillons que Redis prélèvera puis retirera la clé LRU de ceux-ci. La valeur par défaut est 3 mais à toutes fins pratiques, elle est trop faible - et peut signifier que des clés plus anciennes peuvent encore avoir survécu. La définition de cette valeur trop élevée sera une surcharge pour Redis. Vous voudrez peut-être expérimenter un peu ce paramètre avant de le définir. Nous utilisons une valeur de 10.

8

Veuillez lire le chapitre Mémoire virtuelle de la documentation Redis. La partie pertinente:

Le paramètre vm-max-memory Le paramètre vm-max-memory spécifie la quantité de mémoire que Redis est libre d'utiliser avant de commencer à échanger des valeurs sur le disque.

Fondamentalement, si cette limite de mémoire n'est pas atteinte, aucun objet ne sera échangé, Redis fonctionnera avec tous les objets en mémoire comme d'habitude. Cependant, une fois cette limite atteinte, suffisamment d'objets sont échangés pour ramener la mémoire juste en dessous de la limite.

Les objets échangés sont principalement ceux qui ont le plus "âge" (c'est-à-dire le nombre de secondes depuis qu'ils n'ont pas été utilisés), mais la "permutabilité" d'un objet est également proportionnelle au logarithme de sa taille en mémoire. Ainsi, bien que les objets plus anciens soient préférés, les objets plus gros sont échangés en premier lorsqu'ils ont à peu près le même âge.

AVERTISSEMENT: Parce que les clés ne peuvent pas être échangées, Redis ne pourra pas honorer le paramètre vm-max-memory si les clés seules utilisent plus d'espace que la limite.

La meilleure valeur pour ce paramètre est suffisante RAM pour contenir le "jeu de travail" de données. En termes pratiques, donnez simplement à Redis autant de mémoire que possible, et l'échange fonctionnera mieux.

[~ # ~] mise à jour [~ # ~] Comme pour Redis 2.4 (il semble que la documentation officielle du site Redis ne soit pas mise à jour vers cette version) , il n'est pas recommandé d'utiliser VM.

redis.conf dit:

### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of Virtual Memory is strongly discouraged.
3
Ofer Zelig

Définissez des TTL (et laissez Redis gérer l'expiration pour vous) ou publiez vos articles avec vos propres données vieillissantes, peut-être stockées sous la forme d'un ZSET de tuples (horodatage, clé) à partir desquels vous pouvez effectuer votre propre nettoyage du cache selon vos propres besoins.

2
Jim Dennis