Как Redis работает, когда RAM начинает заполняться? - PullRequest
33 голосов
/ 28 декабря 2011

Я мог бы быть полностью отключен, но мое понимание того, как хранилища кэша работали до того, как начали добавлять функции сохранения, заключается в том, что срок действия элементов истекает в зависимости от их ttl.И если бы магазин начал заполнять доступную оперативную память, у каждого из них были бы свои алгоритмы истечения наименее «важных» ключей в магазине.

Теперь я прочитал, что в Redis есть функции персистентности.Но вы можете выключить их.Если вы выключите постоянство, что произойдет, когда ОЗУ заполнится?Как Redis решает, какой срок действия истекает?

Я ожидаю, что у меня будет много данных без TTL, и я хочу убедиться, что Redis может безопасно определить, что истекает.

Ответы [ 4 ]

42 голосов
/ 28 декабря 2011

Я не думаю, что вопрос связан с управлением виртуальной памятью, но больше об истечении срока действия элементов в Redis, что является совершенно другой темой.

В отличие от memcached, Redis - это не только кеш. Таким образом, пользователь должен выбирать политику вытеснения предметов, используя различные механизмы. Вы можете выселить все свои предметы или только их часть.

Общая политика должна быть выбрана в файле конфигурации с параметрами maxmemory и maxmemory-policy, описанными ниже:

# 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

Тогда срок действия отдельного предмета можно установить с помощью следующих команд: EXPIRE ExpireAt Свойство срока действия для каждого элемента полезно для политик volatile- *. Срок действия также можно удалить с помощью PERSIST .

Свойство expiration добавляет небольшие накладные расходы памяти, поэтому его следует использовать только при необходимости.

Наконец, стоит упомянуть, что срок действия части объекта не может быть истек, только сам объект. Например, весь список или набор, соответствующий ключу, может быть просрочен, но отдельные элементы списка или набора не могут.

8 голосов
/ 02 января 2012

Дидье прав, указав, как это сделать.Просто указав некоторые дополнительные элементы (один из которых, кажется, пропущен в его посте):

  1. Укажите максимальный объем памяти, занимающий большую часть доступной памяти на этом узле (оставьте часть для ОС идругие процессы и некоторый буфер).Это гарантирует, что контент никогда не будет разбит на страницы, и поэтому операции выполняются БЫСТРО.
    1. Если вы не устанавливаете TTL / ключи с истекающим сроком действия через приложение, тогда важно использовать подход «allkeys-lru».В противном случае Redis ничего не истечет (потому что ни один из ключей не является энергозависимым), и вы начнете получать ошибки, как только вся память будет израсходована - в основном вы не сможете больше выполнять операции над множествами.
    2. При использовании LRU для удаления ключей важно установить следующую настройку:

maxmemory-samples 10

Это количество выборок.что Redis возьмет и затем удалит ключ LRU среди них.Значение по умолчанию - 3, но для всех практических целей это слишком мало - и может означать, что старые ключи, возможно, все еще сохранились.Установка этого значения слишком высока для Redis.Вы можете поэкспериментировать с этим параметром, прежде чем устанавливать его.Мы используем значение 10.

3 голосов
/ 28 декабря 2011

Пожалуйста, прочитайте главу Виртуальная память в документации Redis. Соответствующая часть:

Настройка vm-max-memory Параметр vm-max-memory указывает, сколько памяти Redis может свободно использовать перед началом обмена значениями на диске.

В основном, если этот предел памяти не достигнут, ни один объект не будет заменен, Redis будет работать со всеми объектами в памяти, как обычно. Как только этот предел достигнут, однако, достаточно объектов обменивается, чтобы вернуть память чуть ниже предела.

Заменяемые объекты - это, в первую очередь, объекты с наибольшим «возрастом» (то есть количеством секунд, с тех пор как они не использовались), но «переключаемость» объекта также пропорциональна логарифму его размера в объем памяти. Таким образом, хотя более старые объекты предпочтительнее, более крупные объекты заменяются первыми, когда они примерно одного возраста.

ПРЕДУПРЕЖДЕНИЕ: Поскольку ключи не могут быть заменены, Redis не сможет выполнить настройку vm-max-memory, если одни ключи используют больше места, чем предел.

Наилучшим значением для этого параметра является достаточный объем ОЗУ для хранения «рабочего набора» данных. В практическом плане просто предоставьте Redis столько памяти, сколько сможете, и обмен будет работать лучше.

UPDATE Что касается Redis 2.4 (кажется, что официальная документация на сайте Redis не обновлена ​​до этой версии), не рекомендуется использовать VM.

redis.conf говорит:

### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of Virtual Memory is strongly discouraged.
2 голосов
/ 28 декабря 2011

Либо установите TTL (и позвольте Redis обработать срок действия для вас), либо опубликуйте ваши элементы с вашими собственными данными устаревания, возможно, сохраненными в виде ZSET из (timestamp, key) кортежей, из которых вы можете выполнить свою собственную очистку кэша в соответствии с вашимисобственные нужды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...