Відповіді:
Якщо у вас включена функція віртуальної пам’яті (я думаю, що нова версія у версії 2.0 або 2.2), то Redis починає зберігати на диску «не так часто використовувані» дані, коли пам’ять закінчується.
Якщо віртуальну пам'ять у Redis вимкнено, це виглядає так, ніби віртуальна пам'ять операційної системи починає звикати (тобто змінюватись), а продуктивність надзвичайно падає.
Тепер ви також можете налаштувати Redis за допомогою параметра maxmemory, який не дозволяє Redis використовувати більше пам'яті (за замовчуванням).
Новіші версії Redis мають різні правила, коли досягається максимальна пам'ять:
Якщо ви вибираєте політику, яка видаляє лише клавіші з набором EXPIRE, тоді, коли у Redis не вистачає пам'яті, схоже, що програма просто перериває операцію malloc (). Тобто, якщо ви намагаєтеся зберегти більше даних, операція просто виходить з ладу.
Деякі посилання для отримання додаткової інформації (оскільки ви не повинні просто приймати моє слово за це):
Від 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
maxmemory-policy
у Redis 3.2 зараз noeviction
: raw.githubusercontent.com/antirez/redis/3.2/redis.conf
Оновлення 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
Я нещодавно почав читати про Редіс, тому я не позитивний. Але я натрапив на кілька ласощів, які можуть бути корисними.
Ось фрагмент від http://antirez.com/post/redis-as-LRU-cache.html :
Інший спосіб використання Redis в якості кешу - це директива maxmemory, функція, яка дозволяє вказати максимальний об'єм пам'яті, який потрібно використовувати. Коли на сервер додаються нові дані, а ліміт пам’яті вже досягнуто, сервер видалить старі дані, видаляючи летючий ключ, тобто ключ із встановленим EXPIRE (тайм-аут), навіть якщо ключ ще далеко закінчується автоматично.
Також Redis 2.0 має режим VM, де всі клавіші повинні вміщуватися в пам'яті, але значення для рідко використовуваних клавіш можуть бути на диску:
Якщо вам цікаво, що насправді реагує 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'.
Нещодавно у мене виникла ситуація без вільної пам’яті, і моє додаток припинилося (писати неможливо, читання були можливі). Запуск сценаріїв PHP зупинилася мертвими на своїх треках посередині і довелося бути kill -9
вручну (навіть після того, як пам'ять була доступні).
Я припускав, що сталася втрата даних (або невідповідність даних), тому я зробив flushdb
і відновився з резервних копій. Урок вивчений? Резервні копії - ваш друг.
Redis - це не кеш-пам'ять, схожа на пам'ять, за замовчуванням (де встановлено maxmemory-policy
параметр noeviction
) всі дані, які ви вводите в redis, не будуть видалені, єдиний виняток - використання EXPIRE.