Сервер Redis v2.8.4 работает на Ubuntu 14.04 VPS с 8 ГБ ОЗУ и 16 ГБ подкачки (на SSD). Однако htop
показывает, что в redis
одиночку занимает 22.4 G
память!
redis-server
в итоге разбился из-за запоминания. Mem
и Swp
оба попадания на 100% затем redis-server
убиваются вместе с другими службами.
От dmesg
:
[165578.047682] Out of memory: Kill process 10155 (redis-server) score 834 or sacrifice child
[165578.047896] Killed process 10155 (redis-server) total-vm:31038376kB, anon-rss:5636092kB, file-rss:0kB
Перезапуск redis-server
после сбоя OOM или из-за того, что service redis-server force-reload
использование памяти сократилось до <100 МБ.
Вопрос: почему redis-server
занимает все больше и больше памяти, пока он не падает? Как мы можем предотвратить это?
Правда ли, что настройка maxmemory
не будет работать, потому что как только redis достигнет maxmemory
предела, он начнет удалять данные?
После перезапуска редис-сервера
Редис версия: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9
Обновить
Когда htop
сообщается, что использование памяти redis-server
составляет 4,4 ГБ ОЗУ и 22,6 Г Своп, объем пространства, занимаемого всеми ключами в Redis, составляет только 60.59636307 MB
, как сообщает rdbtools . Это также объем оперативной памяти, занятой redis-server
сразу после перезагрузки.
INFO ALL
когда redis-server
занимает тонны памяти
mem_fragmentation_ratio:0.19
127.0.0.1:6379> INFO all
# Server
redis_version:2.8.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:a44a05d76f06a5d9
redis_mode:standalone
os:Linux 3.13.0-24-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.2
process_id:26858
run_id:4d4a507b325e567d5ada203a0c65891bcf4d02de
tcp_port:6379
uptime_in_seconds:100011
uptime_in_days:1
hz:10
lru_clock:165668
config_file:/etc/redis/redis.conf
# Clients
connected_clients:60
client_longest_output_list:768774
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:23973468008
used_memory_human:22.33G
used_memory_rss:4563857408
used_memory_peak:24083474760
used_memory_peak_human:22.43G
used_memory_lua:33792
mem_fragmentation_ratio:0.19
mem_allocator:jemalloc-3.4.1
# Persistence
loading:0
rdb_changes_since_last_save:127835154
rdb_bgsave_in_progress:0
rdb_last_save_time:1406716479
rdb_last_bgsave_status:err
rdb_last_bgsave_time_sec:1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
# Stats
total_connections_received:110
total_commands_processed:386765263
instantaneous_ops_per_sec:3002
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:1385878
keyspace_misses:23655
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:82
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:10547.48
used_cpu_user:8240.36
used_cpu_sys_children:201.83
used_cpu_user_children:914.86
# Commandstats
cmdstat_del:calls=136,usec=1407,usec_per_call=10.35
cmdstat_exists:calls=161428,usec=1391252,usec_per_call=8.62
cmdstat_zadd:calls=64149642,usec=936323882,usec_per_call=14.60
cmdstat_zrem:calls=137,usec=2131,usec_per_call=15.55
cmdstat_zremrangebyscore:calls=2293,usec=111905082,usec_per_call=48802.91
cmdstat_zrange:calls=7925,usec=285907448,usec_per_call=36076.65
cmdstat_zrangebyscore:calls=921434,usec=292731002,usec_per_call=317.69
cmdstat_zcount:calls=8,usec=172,usec_per_call=21.50
cmdstat_zrevrange:calls=191184,usec=965447,usec_per_call=5.05
cmdstat_zcard:calls=5180,usec=13502,usec_per_call=2.61
cmdstat_zscore:calls=29856,usec=576044,usec_per_call=19.29
cmdstat_hset:calls=64145124,usec=199407095,usec_per_call=3.11
cmdstat_hget:calls=248487,usec=501220,usec_per_call=2.02
cmdstat_hincrby:calls=128339355,usec=2071112929,usec_per_call=16.14
cmdstat_hgetall:calls=193747,usec=1608260,usec_per_call=8.30
cmdstat_select:calls=1,usec=5,usec_per_call=5.00
cmdstat_rename:calls=134,usec=1090,usec_per_call=8.13
cmdstat_keys:calls=4503,usec=4997628,usec_per_call=1109.84
cmdstat_bgsave:calls=2,usec=20012,usec_per_call=10006.00
cmdstat_type:calls=603,usec=2736,usec_per_call=4.54
cmdstat_multi:calls=64181979,usec=383633610,usec_per_call=5.98
cmdstat_exec:calls=64181979,usec=4403181204,usec_per_call=68.60
cmdstat_info:calls=126,usec=28675,usec_per_call=227.58
# Keyspace
db0:keys=2109,expires=0,avg_ttl=0
bgsave
и перезапускredis-server
приводит к снижению использования памяти до более приемлемого значения 70 МБ. Может ли это быть утечка памяти?INFO ALL
. Если моя догадка верна,mem_fragmentation_ratio
воля заоблачная.redis-server
забирает всю память и вылетает каждый день. Теперь он собирается использовать всю память, поэтому я записал выводINFO ALL
и добавил в OP.mem_fragmentation_ratio:0.19
maxmemory
установлены на 1 ГБ, означает ли это, что когда использование памяти Redis достигает 1 ГБ, выселение все равно удалит данные? Поскольку Redismem_fragmentation_ratio
есть0.19
, означает ли это, что в swap слишком много фрагментации, или слишком много, или в обоих? Есть ли способ уменьшить фрагментацию?Это почти наверняка фрагментация памяти, поскольку Redis хорошо известен и любим в производстве, и вы, вероятно, не обнаружили утечку памяти.
Рекомендации по настройке размера пула не помогут при фрагментации. Вам нужно будет конкретно уменьшить размер Redis - меньше, чем ваш фактический объем памяти - потому что Redis не может учитывать фрагментацию - но, с точки зрения краткого ответа, вам придется это сделать и начать планировать перезапуск вашего сервера часто.
Мое эмпирическое правило, работающее с различными операционными системами и базами данных в памяти, заключается в том, что вам нужно в 2 раза больше фактической памяти, а объем памяти стабилизируется примерно через 2 недели.
Однако это зависит от ваших фактических моделей распределения и используемого вами распределителя памяти.
Сейчас лучшим распределителем памяти, который я нашел для серверов, является JEMalloc. Мы используем его в Aerospike сейчас, чтобы уменьшить (почти удалить) долговременную фрагментацию памяти. JEMalloc имеет функцию, которая позволяет вам создавать «арену» (пул) памяти и при любом распределении выбирать, какой пул, тем самым предоставляя вам ресурсы одинакового размера и управлять аналогичными распределениями времени жизни памяти. Это была большая победа для нас в тех случаях, которые вы обсуждаете.
В этом отношении движок Zend PHP сложен, потому что все выделения внутри него находятся либо в памяти для каждой транзакции, либо в глобальной памяти. Для каждой транзакции память освобождается одним махом в конце транзакции и, таким образом, может быть очень эффективной.
Если вы работаете в Linux, распределитель памяти ядра (Clib) сделал несколько изгибов и поворотов, и от того, какая версия вы используете, будет резко зависеть степень фрагментации, как и от фактического шаблона приложения. Например, некоторые распределители намного лучше, когда вы немного растете объекты, а некоторые намного хуже. К сожалению, даже обсуждение с другими пользователями Redis означает разговор о том, какую ОС и какую версию ОС вы используете.
Тот факт, что вы можете перезапустить сервер (из постоянства) и вернуть память, может означать утечку, но, скорее всего, указывает на фрагментацию.
источник
maxmemory
?