Redis nimmt alle Speicher und Abstürze auf


12

Ein Redis Server v2.8.4 läuft auf einem Ubuntu 14.04 VPS mit 8 GB RAM und 16 GB Swap Space (auf SSDs). htopZeigt jedoch , dass redisallein 22.4 GSpeicherplatz beansprucht!

redis-serverstürzte schließlich wegen aus dem Gedächtnis. Memund Swpbeide Treffer 100% werden dann redis-serverzusammen mit anderen Diensten getötet.

Von 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

Ein Neustart redis-servervon einem OOM-Absturz oder einem führt dazu, service redis-server force-reloaddass die Speichernutzung auf <100 MB sinkt.

Frage: Warum belegt es redis-serverimmer mehr Speicher, bis es abstürzt? Wie können wir das verhindern?

Stimmt es, dass die Einstellung maxmemorynicht funktioniert, denn sobald Redis das maxmemoryLimit erreicht, werden Daten entfernt?

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Nach dem Neustart von redis-server

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Redis-Version: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9


Aktualisieren

Wenn htopBerichte über die Speicherauslastung redis-server4.4G RAM und 22,6 g Swap zu sein, ist die Menge an Raum , der durch alle Schlüssel in redis aufgenommen nur 60.59636307 MB, wie berichtet rdbtools . Dies ist auch die Menge an RAM, die redis-serverdirekt nach dem Neustart belegt wird.

INFO ALLWann redis-servernimmt Tonnen von Speicher in Anspruch

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

Antworten:


8
  1. Verwenden Sie die Option maxmemory, um ein Limit festzulegen, um wie viel Ihre Redis-Datenbank ebenfalls wachsen kann. Andernfalls wächst Redis, bis das Betriebssystem es beendet, sobald der Speicher erschöpft ist (gemäß Ihrer aktuellen Erfahrung).
  2. Die Verwendung von maxmemorysollte gekoppelt sein mit maxmemory-policy- Sie können je nach den Anforderungen Ihres Anwendungsfalls aus verschiedenen Räumungsrichtlinien auswählen. Wenn Sie beispielsweise die allkeys-lruRäumungsrichtlinie verwenden, beginnt Redis tatsächlich mit der Räumung (der zuletzt verwendeten) Daten, sobald maxmemorydiese erreicht wurden. Alternativ können Sie Redis anweisen, nur ablaufende Daten mit den Richtlinien volatile-lruoder zu volatile-randomentfernen. Zuletzt können Sie die Richtlinie auf festlegen, noevictionaber das würde bedeuten, dass Redis nach Erschöpfung des Speichers weitere Schreibvorgänge mit einer OOM-Nachricht ablehnt.

Bearbeiten:

Erster Swap deaktivieren - Redis und Swap lassen sich nicht leicht mischen und dies kann sicherlich zu Langsamkeit führen.

Machen Sie free -mstatt oben auch das vollständige Bild des RAM-Status ( http://www.linuxatemyram.com/ ).


Vielen Dank, ich bin verwirrt darüber, warum die Speichernutzung weiter zunimmt. Wenn Sie jedoch ein bgsaveund einen Neustart durchführen redis-server, sinkt die Speichernutzung auf einen vernünftigeren Wert von 70 MB. Könnte dies ein Speicherverlust sein?
Nyxynyx

Möglich, aber unwahrscheinlich (oder andere Leute hätten es gemeldet) ... Wahrscheinlicher ein Fragmentierungsproblem. Wenn das nächste Mal passiert, poste die Ausgabe deiner Redis INFO ALL. Wenn meine Vermutung richtig ist, ist der mem_fragmentation_ratioWille himmelhoch.
Itamar Haber

redis-serververschlingt die ganze Erinnerung und stürzt jeden Tag ab. Es ist dabei, den gesamten Speicher zu verbrauchen, also habe ich die Ausgabe von erfasst INFO ALLund zum OP hinzugefügt. mem_fragmentation_ratio:0.19
Nyxynyx

Wenn die Redis-Datensätze 250 MB nicht überschreiten und maxmemoryauf 1 GB festgelegt sind, bedeutet dies, dass bei einer Redis-Mem-Nutzung von 1 GB durch die Räumung weiterhin Daten entfernt werden? Da redis der mem_fragmentation_ratioist 0.19, bedeutet es , dass zu viel Fragmentierung Theres, oder zu viel ist in Swap oder beides gespeichert? Wie kann die Fragmentierung reduziert werden?
Nyxynyx

Wenn der Redis-Server aufgrund von OOM abstürzt, zeigt rdbtools, dass die Schlüssel in Redis nur 60 MB belegen. Das sieht nach extrem schwerer Fragmentierung aus? Wenn man bedenkt, dass es 4,4 GB RAM und 22,4 GB Swap beansprucht.
Nyxynyx

5

Dies ist mit ziemlicher Sicherheit eine Speicherfragmentierung, da Redis in der Produktion bekannt und beliebt ist und Sie wahrscheinlich kein Speicherleck gefunden haben.

Die Empfehlungen zum Festlegen der Größe des Pools helfen nicht bei der Fragmentierung. Sie müssen die Redis-Größe gezielt verringern - niedriger als Ihre tatsächliche Speichergröße -, da Redis keine Fragmentierung berücksichtigen kann. In Bezug auf eine kurze Antwort müssen Sie dies jedoch tun und einen Neustart planen Server häufig.

Meine Faustregel bei der Arbeit mit einer Vielzahl von Betriebssystemen und In-Memory-Datenbanken lautet, dass Sie das Zweifache Ihres tatsächlichen Speichers benötigen und sich die Speichergröße in etwa 2 Wochen stabilisieren wird.

Dies hängt jedoch von Ihren tatsächlichen Zuordnungsmustern und dem von Ihnen verwendeten Speicherzuweiser ab.

Derzeit ist JEMalloc der beste Speicherzuweiser, den ich für Server gefunden habe. Wir verwenden es jetzt bei Aerospike , um die Fragmentierung des Langzeitgedächtnisses zu reduzieren (fast zu entfernen). JEMalloc verfügt über eine Funktion, mit der Sie eine Speicher- "Arena" (Pool) erstellen und bei jeder Zuweisung auswählen können, welcher Pool verwendet werden soll. Auf diese Weise erhalten Sie Zuordnungen gleicher Größe und können ähnliche Zuordnungen für die Speicherlebensdauer verwalten. Es war ein großer Gewinn für uns in den Fällen, die Sie diskutieren.

Die Zend PHP-Engine ist in dieser Hinsicht hochentwickelt, da sich alle Zuordnungen innerhalb der Engine entweder im Transaktionsspeicher oder im globalen Speicher befinden. Pro Transaktion wird der Speicher am Ende der Transaktion auf einen Schlag freigegeben und kann daher sehr effizient sein.

Wenn Sie unter Linux arbeiten, hat der Kernel-Speicherzuweiser (Clib) eine Reihe von Drehungen und Wendungen vorgenommen. Welche Version Sie verwenden, bestimmt den Grad der Fragmentierung ebenso wie das tatsächliche Anwendungsmuster erheblich. Zum Beispiel sind einige Allokatoren viel besser, wenn Sie Objekte leicht wachsen lassen, andere sind viel schlechter. Selbst wenn Sie mit anderen Redis-Benutzern diskutieren, müssen Sie leider darüber sprechen, welches Betriebssystem und welche Betriebssystemversion Sie verwenden.

Die Tatsache, dass Sie den Server neu starten können (aus Gründen der Persistenz) und Ihren Speicher zurückerhalten können, könnte ein Leck bedeuten, deutet jedoch eher auf eine Fragmentierung hin.

  1. Swap nicht zulassen (es ist besser für OOM als zu tauschen, für Redis)
  2. Verringern Sie die Speichergröße von redis
  3. Nach einem Zeitplan neu starten

Wie würden Sie die Speichergröße durch Anpassen verringern maxmemory?
Nyxynyx
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.