Un serveur redis v2.8.4 fonctionne sur un VPS Ubuntu 14.04 avec 8 Go RAM et 16 Go d'espace de swap (sur SSD). Cependant htop
montre que redis
seul prend 22.4 G
de mémoire!
redis-server
s'est finalement écrasé en raison d'une rupture de mémoire. Mem
et Swp
frappe à 100% puis redis-server
est tué avec d'autres services.
De 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
Redémarrage redis-server
depuis etiher un plantage OOM ou un service redis-server force-reload
fait chuter l'utilisation de la mémoire à <100 Mo.
Question: Pourquoi redis-server
occupe de plus en plus de mémoire jusqu'à ce qu'elle se bloque? Comment éviter cela?
Est-il vrai que le paramètre maxmemory
ne fonctionnera pas car une fois que redis atteint la limite maxmemory
, il commencera à supprimer les données?
Après redémarrage du serveur redis
Version redis: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9
Lorsque htop
signale l'utilisation de la mémoire de redis-server
à 4.4G RAM et 22.6G Swap, la quantité d'espace occupée par toutes les touches dans redis est seulement 60.59636307 MB
, tel que rapporté par rdbtools . C'est également le montant de RAM occupé par redis-server
juste après le redémarrage.
INFO ALL
quand redis-server
prend des tonnes de mémoire
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
maxmemory
pour définir une limite à la croissance de votre base de données Redis. Sinon, Redis grandira jusqu'à ce que le système d'exploitation le tue une fois la mémoire épuisée (selon votre expérience actuelle).maxmemory
doit être associée à maxmemory-policy
- vous pouvez choisir parmi différentes politiques d'expulsion en fonction des exigences de votre cas d'utilisation. Par exemple, si vous utilisez le allkeys-lru
politique d'expulsion, Redis commencera en effet à expulser les données (les moins récemment utilisées) une fois que maxmemory
aura été atteint. Vous pouvez également demander à Redis d'expulser uniquement les données expirables avec le volatile-lru
ou volatile-random
Stratégies. Enfin, vous pouvez définir la stratégie sur noeviction
mais cela signifierait qu'une fois la mémoire épuisée, Redis refusera les écritures supplémentaires avec un message OOM.Modifier:
Tout d'abord désactiver le swap - Redis et swap ne se mélangent pas facilement, ce qui peut certainement provoquer une lenteur.
Faites aussi free -m
au lieu du haut pour une image complète de l'état de votre RAM ( http://www.linuxatemyram.com/ ).
Il s'agit presque certainement d'une fragmentation de la mémoire, car redis est bien connu et apprécié en production et vous n'avez probablement pas trouvé de fuite de mémoire.
Les recommandations sur la définition de la taille du pool n'aideront pas à la fragmentation. Vous devrez spécifiquement réduire la taille de Redis - inférieure à la taille réelle de votre mémoire - car Redis ne peut pas tenir compte de la fragmentation - mais, en termes de réponse courte, vous devrez le faire et commencer à planifier le redémarrage de votre serveurs fréquemment.
Ma règle de base pour travailler avec une variété de systèmes d'exploitation et de bases de données en mémoire est que vous avez besoin de 2x votre mémoire réelle, et la taille de la mémoire se stabilisera dans environ 2 semaines.
Cependant, cela dépend de vos modèles d'allocation réels et de l'allocateur de mémoire que vous utilisez.
À l'heure actuelle, le meilleur allocateur de mémoire que j'ai trouvé pour les serveurs est JEMalloc. Nous l'utilisons à Aerospike maintenant pour réduire (presque supprimer) la fragmentation de la mémoire à long terme. JEMalloc a une fonctionnalité qui vous permet de créer une "arène" de mémoire (pool), et sur n'importe quelle allocation, choisissez quel pool, vous donnant ainsi des allocations de même taille et de gérer des allocations de durée de vie de mémoire similaires. Cela a été une grande victoire pour nous dans le genre de cas dont vous discutez.
Le moteur Zend PHP est sophistiqué à cet égard, car toutes les allocations à l'intérieur du moteur sont soit dans la mémoire par transaction, soit dans la mémoire globale. La mémoire par transaction est libérée d'un coup à la fin de la transaction et peut donc être très efficace.
Si vous êtes sous Linux, l'allocateur de mémoire du noyau (Clib) a pris un certain nombre de rebondissements, et la version sur laquelle vous vous trouvez déterminera considérablement la quantité de fragmentation, tout comme le modèle d'application réel. Par exemple, certains allocateurs sont bien meilleurs lorsque vous faites légèrement pousser des objets, certains sont bien pires. Malheureusement, même discuter avec d'autres utilisateurs de Redis signifie parler du système d'exploitation et de la version du système d'exploitation que vous utilisez.
Le fait que vous puissiez redémarrer le serveur (à partir de la persistance) et récupérer votre mémoire peut signifier une fuite, mais indique plus probablement une fragmentation.