it-swarm.com.de

Redis nimmt alle Speicher und Abstürze auf

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). htop zeigt jedoch, dass redis allein nimmt auf 22.4 G der Erinnerung!

redis-server stürzte schließlich wegen Nichterinnerung ab. Mem und Swp treffen beide 100%, dann redis-server wird zusammen 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

Neustart redis-server von etiher ein OOM-Absturz oder ein service redis-server force-reload bewirkt, dass die Speichernutzung auf <100 MB sinkt.

Frage: Warum funktioniert redis-server immer mehr Speicher belegen, bis es abstürzt? Wie können wir das verhindern?

Stimmt es, dass die Einstellung maxmemory nicht funktioniert, da Redis Daten entfernt, sobald das Limit maxmemory erreicht ist?

enter image description hereenter image description here

Nach dem Neustart von redis-server

enter image description hereenter image description here

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


Aktualisieren

Wenn htop die Speichernutzung von redis-server 4,4G RAM und 22,6G Swap, der von allen Tasten in redis belegte Speicherplatz beträgt nur 60.59636307 MB, wie von rdbtools gemeldet. Dies ist auch die Menge von RAM, die von redis-server direkt nach dem Neustart.

INFO ALL wann redis-server nimmt 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
12
Nyxynyx
  1. Verwenden Sie 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 maxmemory sollte mit maxmemory-policy Gekoppelt sein. Je nach den Anforderungen Ihres Anwendungsfalls können Sie aus verschiedenen Räumungsrichtlinien auswählen. Wenn Sie beispielsweise die Räumungsrichtlinie allkeys-lru Verwenden, beginnt Redis tatsächlich mit der Räumung (der zuletzt verwendeten) Daten, sobald maxmemory erreicht wurde. Alternativ können Sie Redis anweisen, nur ablaufende Daten mit den Richtlinien volatile-lru Oder volatile-random Zu entfernen. Zuletzt können Sie die Richtlinie auf noeviction setzen, aber das würde bedeuten, dass Redis nach Erschöpfung des Speichers weitere Schreibvorgänge mit einer OOM-Nachricht verweigert.

Bearbeiten:

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

Machen Sie auch free -m Statt oben, um das vollständige Bild des RAM-Status zu erhalten ( http://www.linuxatemyram.com/ ).

8
Itamar Haber

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. Der Transaktionsspeicher wird auf einen Schlag bei der freigegeben Ende der Transaktion und kann daher sehr effizient sein.

Wenn Sie unter Linux arbeiten, hat der Kernel-Speicherzuweiser (Clib) einige Wendungen genommen, und welche Version Sie verwenden, bestimmt das Ausmaß der Fragmentierung sowie 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
5
Brian Bulkowski