Redisがすべてのメモリとクラッシュを占有する


12

Redisサーバーv2.8.4は、8 GBのRAMと16 GBのスワップスペース(SSD上)を備えたUbuntu 14.04 VPSで実行されています。ただしhtopredis一人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-serverOOMクラッシュまたはから再起動すると、service redis-server force-reloadメモリ使用量が100MB未満に低下します。

質問:redis-serverクラッシュするまで、メモリをどんどん占有するのはなぜですか?どうすればこれを防ぐことができますか?

maxmemoryredisがmaxmemory制限に達するとデータの削除を開始するため、設定が機能しないのは本当ですか?

ここに画像の説明を入力してください ここに画像の説明を入力してください

redis-serverを再起動した後

ここに画像の説明を入力してください ここに画像の説明を入力してください

Redisバージョン: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9


更新

ときhtopのメモリ使用量を報告redis-server4.4gのRAMと22.6Gスワップされることを、Redisの内のすべてのキーによって取り込まれたスペースの量はわずかである60.59636307 MBことで報告されたように、rdbtools。これは、redis-server再起動直後に使用されるRAMの量でもあります。

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

回答:


8
  1. を使用しmaxmemoryて、Redisデータベースも拡張できる量に制限を設定します。そうしないと、メモリが使い果たされると(現在の経験に基づいて)、RedisはOSが強制終了するまで大きくなります。
  2. の使用方法maxmemoryと組み合わせるmaxmemory-policy必要があります-ユースケースの要件に応じて、さまざまな排除ポリシーから選択できます。たとえば、allkeys-lru立ち退きポリシーを使用する場合、Redisは実際に到達すると(実際に最も長く使用されていない)データの削除を開始しmaxmemoryます。または、volatile-lruor volatile-randomポリシーを使用して、有効期限が切れたデータのみを削除するようにRedisに指示できます。最後に、ポリシーをに設定できますが、noevictionメモリが使い果たされると、RedisはOOMメッセージで以降の書き込みを拒否します。

編集:

最初にスワップを無効にします-Redisとswapは簡単に混ざりません。これは確かに速度低下を引き起こす可能性があります。

free -mRAMの状態の全体像を確認するために、topの代わりにも実行します(http://www.linuxatemyram.com/)。


ありがとう、メモリ使用量が増え続ける理由について混乱していますが、を実行しbgsaveて再起動するredis-serverと、メモリ使用量がより妥当な値の70 MBに下がります。これはメモリリークの可能性がありますか?
Nyxynyx 2014

可能ですが、そうではありません(または他の人が報告したはずです)...おそらくフラグメンテーションの問題です。次回は、Redis 'の出力を投稿してくださいINFO ALL。私の推測が正しい場合、mem_fragmentation_ratio意志は空高くなります。
Itamar Haber 14

redis-serverすべてのメモリを占有し、毎日クラッシュします。今すぐすべてのメモリを使い果たしそうなので、の出力をキャプチャINFO ALLしてOPに追加しました。mem_fragmentation_ratio:0.19
Nyxynyx 2014

Redisデータセットが250 MBを超えずmaxmemory、1 GBに設定されている場合、これは、Redisのメモリ使用量が1 GBに達しても、エビクションによってデータが削除されることを意味しますか?redis mem_fragmentation_ratioはなので0.19、断片化が多すぎるか、スワップに格納されている量が多すぎるか、またはその両方でしょうか?断片化を減らす方法はありますか?
Nyxynyx 2014

OOMが原因でredis-serverがクラッシュしようとすると、rdbtoolsはredisのキーが60MBしか使用しないことを示します。これは非常に深刻な断片化のように見えますか?4.4GBのRAMと22.4Gのスワップを占めることを考慮してください。
Nyxynyx 2014

5

これはほぼ間違いなくメモリの断片化です。redisはよく知られており、本番環境で愛されており、おそらくメモリリークは発見されていません。

プールのサイズの設定に関する推奨事項は、断片化には役立ちません。Redisは断片化を考慮できないため、Redisサイズを実際のメモリサイズよりも具体的に小さくする必要があります。ただし、簡単に言えば、それを行い、再起動の計画を立てる必要があります。頻繁にサーバー。

さまざまなオペレーティングシステムとインメモリデータベースを操作する私の経験則では、実際のメモリの2倍が必要で、メモリサイズは約2週間で安定します。

ただし、それは実際の割り当てパターンと、使用しているメモリアロケータによって異なります。

現在、サーバー用に見つけた最高のメモリアロケータはJEMallocです。私たちはこれをAerospikeで使用して、長期的なメモリの断片化を軽減(ほぼ削除)します。JEMallocには、メモリ「アリーナ」(プール)を作成し、任意の割り当てでどのプールを選択するかを選択できる機能があり、これにより、同じサイズの割り当てが可能になり、同様のメモリ寿命の割り当てを管理できます。あなたが議論しているようなケースでは、それは私たちにとって大きな勝利でした。

Zend PHPエンジンはこの点で洗練されています。これは、エンジン内のすべての割り当てがトランザクションごとのメモリまたはグローバルメモリのいずれかにあるためです。トランザクションごとのメモリは、トランザクションの終了時に1急降下で解放されるため、非常に効率的です。

Linuxを使用している場合、カーネルメモリアロケータ(Clib)には多くの工夫が施されており、実際のアプリケーションパターンと同様に、どのバージョンを使用しているかによって、断片化の量が劇的に決まります。たとえば、オブジェクトをわずかに増やしている場合は、一部のアロケータははるかに優れていますが、一部のアロケータははるかに悪いです。残念ながら、他のRedisユーザーと話し合うことは、使用しているOSとOSのバージョンについて話すことを意味します。

サーバーを(永続化から)再起動してメモリを元に戻すことができるという事実は、リークを意味する可能性がありますが、フラグメンテーションを指している可能性が高くなります。

  1. スワップを許可しない(redisの場合、スワップよりもOOMの方が良い)
  2. redisのメモリサイズを減らす
  3. 定期的に再開する

調整することで、メモリサイズをどのように減らしmaxmemoryますか?
Nyxynyx 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.