2011-12-28 1 views
27

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

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

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

ответ

35

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

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

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

# 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.

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

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

+0

Отлично, спасибо. Таким образом, алгоритм LRU с defaul - это именно то, что я хотел. Просто нужно настроить его так, чтобы он был «государственным» сервером. – joedevon

2

Прочтите главу Virtual Memory из документации Redis. Соответствующая часть:

Заходящее Параметр VM-макс-памяти VM-макс-памяти определяет, сколько памяти Redis волен использовать перед началом свапирования значения на диске.

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

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

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

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

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

redis.conf говорит:

### WARNING! Virtual Memory is deprecated in Redis 2.4 
### The use of Virtual Memory is strongly discouraged. 
+0

Поскольку VIrtual Memory устарела, какой лучший способ использовать память на диске при достижении предела памяти RAM? – harsimranb

+1

@harsimranb Не надо. Если вы попадаете на сцену, где вам нужен диск, вы неправильно использовали Redis (или вы должны увеличить объем оперативной памяти, зависит от вашего варианта использования). –

2

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

8

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

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

maxmemory-образцы 10

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

+0

Спасибо за полезное дополнение. – joedevon

+0

Вы совершенно правы @Gur, я просто проверил его с различными значениями maxmemory и maxmemory-policy. –

 Смежные вопросы

  • Нет связанных вопросов^_^