Redis tüm hafızayı ve çökmeleri kaplıyor


12

Bir redis sunucusu v2.8.4, 8 GB RAM ve 16 GB takas alanı (SSD'lerde) olan bir Ubuntu 14.04 VPS'de çalışıyor. Ancak tek başına hafızayı htopaldığını gösterir !redis22.4 G

redis-serversonunda memeory nedeniyle çöktü. Memve Swpher ikisi de% 100 isabet ederse redis-serverdiğer servislerle birlikte öldürülür.

Gönderen 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-serverBir OOM kilitlenmesinden yeniden başlatmak veya service redis-server force-reloadbellek kullanımının 100 MB'tan düşük olmasına neden olur.

Soru:redis-server Çökene kadar neden daha fazla bellek kaplıyor? Bunu nasıl önleyebiliriz?

maxmemoryYeniden ayarlama maxmemorysınıra ulaştığında verilerin kaldırılmaya başlayacağı için ayarın çalışmayacağı doğru mu?

resim açıklamasını buraya girin resim açıklamasını buraya girin

Redis-server'ı yeniden başlattıktan sonra

resim açıklamasını buraya girin resim açıklamasını buraya girin

Yeniden sürüm sürümü: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9


Güncelleme

Ne zaman htopraporlar bellek kullanımı redis-server4.4g RAM ve 22.6g Takas olmak, REDIS anahtarları tüm kapladığı alan miktarı sadece 60.59636307 MBbildirdiği şekilde rdbtools . Bu aynı zamanda redis-serveryeniden başlatıldıktan hemen sonra alınan RAM miktarıdır .

INFO ALLne zaman redis-serverbellek ton kadar alıyor

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

Yanıtlar:


8
  1. maxmemoryRedis veritabanınızın da ne kadar büyüyebileceğine ilişkin bir sınır belirlemek için kullanın . Bunu yapmazsanız, Redis bellek tükendiğinde işletim sistemi onu öldürene kadar büyür (mevcut deneyiminize göre).
  2. Kullanımı maxmemoryile eşleştirilmelidir maxmemory-policy- kullanım durumunuzun gereksinimlerine bağlı olarak farklı tahliye politikaları arasından seçim yapabilirsiniz. Örneğin, allkeys-lrutahliye politikasını kullanırsanız, Redis gerçekten maxmemoryulaşıldıktan sonra (en son kullanılan) verileri çıkarmaya başlayacaktır . Alternatif olarak, Redis'e volatile-lruveya volatile-randompolitikalarıyla yalnızca süresi doldurulabilir verileri tahliye etmesini isteyebilirsiniz . Son olarak, politikayı şu şekilde ayarlayabilirsiniz: noevictionancak bu, bellek bittiğinde Redis'in OOM mesajıyla daha fazla yazmayı reddedeceği anlamına gelir.

Düzenle:

Öncelikle swap'ı devre dışı bırakın - Redis ve swap kolayca karışmaz ve bu kesinlikle yavaşlığa neden olabilir.

Ayrıca free -mRAM'inizin durumunun tam resmi ( http://www.linuxatemyram.com/ ) için üst yerine yapın .


Teşekkür ederim, bellek kullanımının neden artmaya devam ettiği konusunda kafam karıştı, ancak bir bgsaveve yeniden başlatma redis-serverbellek kullanımının 70 MB daha makul bir değere düşmesine neden oluyor. Bu bir bellek sızıntısı olabilir mi?
Nyxynyx

Olası ama olası değil (veya başkaları bunu rapor ederdi) ... Büyük olasılıkla bir parçalanma sorunu. Bir dahaki sefere, Redis'inizin çıktısını gönderin INFO ALL. Eğer tahminim doğruysa, mem_fragmentation_ratioirade gök yüksekliğindedir.
Itamar Haber

redis-servertüm hafızayı kapar ve her gün çöker. Artık tüm belleği kullanmak üzere, bu yüzden INFO ALLOP'nin çıktısını yakaladım ve OP'ye ekledim. mem_fragmentation_ratio:0.19
Nyxynyx

Redis veri kümeleri 250 MB'ı geçmezse ve maxmemory1 GB olarak ayarlanırsa, redis'in bellek kullanımı 1 GB'a ulaştığında tahliye yine de verileri kaldıracağı anlamına mı gelir? Redis olduğu mem_fragmentation_ratioiçin 0.19, çok fazla parçalanma olduğu veya takasta veya her ikisinin de çok fazla depolandığı anlamına mı geliyor? Parçalanmayı azaltmanın bir yolu var mı?
Nyxynyx

Redis-server OOM nedeniyle çökmek üzereyken, rdbtools redis içindeki anahtarların sadece 60 MB aldığını gösterir. Bu son derece ciddi bir parçalanma gibi mi görünüyor? 4.4GB RAM ve 22.4G Swap alanından yola çıkarak.
Nyxynyx

5

Bu neredeyse kesinlikle bellek parçalanmasıdır, çünkü redis iyi bilinir ve üretimde sevilir ve muhtemelen bir bellek sızıntısı bulamazsınız.

Havuzun boyutunu ayarlama hakkındaki öneriler parçalanmaya yardımcı olmaz. Redis boyutunu - gerçek bellek boyutundan daha küçük - özellikle azaltmanız gerekir, çünkü Redis parçalanmayı hesaba katamaz - ancak kısa bir yanıt olarak bunu yapmanız ve yeniden başlatma planınızı başlatmanız gerekir. sunucuları sık.

Çeşitli işletim sistemleri ve bellek içi veritabanlarıyla çalışmanın temel kuralı, gerçek belleğinizin 2 katına ihtiyacınız olması ve bellek boyutunun yaklaşık 2 hafta içinde sabitlenmesidir.

Ancak bu, gerçek ayırma düzenlerinize ve kullandığınız bellek ayırıcıya bağlıdır.

Şu anda, sunucular için bulduğum en iyi bellek ayırıcı JEMalloc. Biz de kullanmak Aerospike uzun süreli bellek parçalanması şimdi azaltmak için (neredeyse çıkarın). JEMalloc, bir bellek "arena" (havuz) oluşturmanıza ve herhangi bir ayırmada hangi havuzu seçmenize, böylece size benzer boyutta tahsisler vermenize ve benzer bellek yaşam boyu tahsislerini yönetmenize izin veren bir özelliğe sahiptir. Tartıştığınız davalarda bizim için büyük bir kazanç oldu.

Zend PHP motoru bu bakımdan karmaşıktır, çünkü motor içindeki tüm ayırmalar işlem başına bellekte veya global bellekte bulunur. İşlem başına bellek, işlemin sonunda tek tuşla serbest bırakılır ve böylece çok verimli olabilir.

Linux'taysanız, çekirdek bellek ayırıcısı (Clib) bir dizi bükülme ve dönüş aldı ve hangi sürümde olduğunuz, gerçek uygulama modeli gibi parçalanma miktarını önemli ölçüde belirleyecektir. Örneğin, nesneler biraz büyürken bazı ayırıcılar daha iyidir, bazıları daha kötüdür. Ne yazık ki, diğer Redis kullanıcılarıyla tartışmak bile hangi işletim sistemi ve hangi işletim sistemi sürümünü kullandığınız hakkında konuşmak anlamına gelir.

Sunucuyu (kalıcılıktan) yeniden başlatabileceğiniz ve belleğinizi geri alabileceğiniz bir sızıntı anlamına gelebilir, ancak daha fazla parçalanma anlamına gelebilir.

  1. Takas işlemine izin verme (OOM için takas etmekten daha iyi, redis için)
  2. Redis 'in bellek boyutunu küçültme
  3. Bir zamanlamaya göre yeniden başlat

Ayarlayarak bellek boyutunu nasıl azaltabilirsiniz maxmemory?
Nyxynyx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.