Redis सभी मेमोरी और क्रैश को लेता है


12

एक रेडिस सर्वर v2.8.4 8 जीबी रैम और 16 जीबी स्वैप स्पेस (एसएसडी पर) के साथ उबंटू 14.04 वीपीएस पर चल रहा है। हालाँकि यह htopदर्शाता है कि redisअकेले ही 22.4 Gस्मृति को ऊपर ले जा रहा है!

redis-serverमेमरी से बाहर होने के कारण अंततः दुर्घटनाग्रस्त हो गया। Memऔर Swpदोनों redis-serverअन्य सेवाओं के साथ 100% मारा जाता है।

से 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-serverएक OOM क्रैश या एक service redis-server force-reload100% ड्रॉप करने के लिए स्मृति उपयोग का कारण बनता है etiher से पुनरारंभ करना ।

प्रश्न:redis-server दुर्घटनाग्रस्त होने तक अधिक से अधिक मेमोरी पर कब्जा क्यों करता है? हम इसे कैसे रोक सकते हैं?

क्या यह सच है कि सेटिंग maxmemoryकाम नहीं करेगी क्योंकि एक बार जब रेडिस maxmemoryसीमा को हिट करता है, तो यह डेटा को निकालना शुरू कर देगा?

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

रेडिस-सर्वर को पुनरारंभ करने के बाद

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

रेडिस संस्करण: 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पुनरारंभ होने के बाद सही द्वारा ली गई रैम की मात्रा है ।

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पहुँच जाने के बाद वास्तव में (कम से कम हाल ही में उपयोग किए गए) डेटा को निकालना शुरू कर देगा । वैकल्पिक रूप से, आप Redis को निर्देश volatile-lruया volatile-randomनीतियों के साथ केवल एक्सपायर-सक्षम डेटा को बेदखल करने का निर्देश दे सकते हैं। अंत में, आप पॉलिसी को सेट कर सकते हैं noevictionलेकिन इसका मतलब यह होगा कि एक बार मेमोरी समाप्त हो जाने के बाद, रेडिस OOM संदेश के साथ आगे लिखने से इनकार करेगा।

संपादित करें:

पहले स्वैप को अक्षम करें - रेडिस और स्वैप आसानी से मिश्रण नहीं करते हैं और यह निश्चित रूप से सुस्ती पैदा कर सकता है।

free -mअपने रैम की स्थिति ( http://www.linuxatemyram.com/ ) की पूरी तस्वीर के लिए ऊपर की बजाय भी करें ।


धन्यवाद, मैं उलझन में हूं कि मेमोरी का उपयोग क्यों बढ़ रहा है, फिर भी ए bgsaveऔर रीस्टार्ट करने redis-serverसे मेमोरी का उपयोग 70 एमबी के अधिक उचित मूल्य तक गिर जाता है। यह एक स्मृति रिसाव हो सकता है?
Nyxynyx

संभव है, लेकिन संभावना नहीं है (या अन्य लोगों ने इसे रिपोर्ट किया होगा) ... अधिक संभावना एक विखंडन मुद्दा है। अगली बार ऐसा होने पर, अपने Redis 'के आउटपुट को पोस्ट करें INFO ALL। यदि मेरा अनुमान सही है, तो mem_fragmentation_ratioआसमान से ऊँची इच्छाशक्ति।
इटाराम हैबर

redis-serverसभी मेमोरी को हॉग करता है और हर रोज क्रैश होता है। अब यह सभी मेमोरी का उपयोग करने वाला है, इसलिए मैंने इसका आउटपुट कैप्चर किया है INFO ALLऔर ओपी में जोड़ा है। mem_fragmentation_ratio:0.19
Nyxynyx

यदि रेडिस डेटासेट 250MB से अधिक नहीं है और maxmemory1 जीबी पर सेट है, तो क्या इसका मतलब यह है कि जब रेडिस का मेम उपयोग 1 जीबी हिट करता है, तब भी बेदखल डेटा को हटा देगा? रेडिस के बाद mem_fragmentation_ratioसे 0.19, क्या इसका मतलब है कि बहुत अधिक विखंडन, या बहुत अधिक स्वैप में संग्रहीत है, या दोनों? विखंडन को कम करने का कोई तरीका?
Nyxynyx

जब OOM के कारण रेडिस-सर्वर क्रैश होने वाला होता है, तो rdbtools दर्शाता है कि रेडिस में कीज़ केवल 60MB तक लगते हैं। यह अत्यंत गंभीर विखंडन जैसा दिखता है? इसके 4.4GB RAM और 22.4G स्वैप को ध्यान में रखते हुए।
19x पर Nyxynyx

5

यह लगभग निश्चित रूप से स्मृति विखंडन है, क्योंकि रेडिस अच्छी तरह से जाना जाता है और उत्पादन में प्यार करता है और आपको शायद मेमोरी रिसाव नहीं मिला है।

पूल का आकार निर्धारित करने के बारे में सिफारिशें विखंडन में मदद नहीं करेंगी। आपको विशेष रूप से Redis का आकार कम करना होगा - अपने वास्तविक मेमोरी साइज़ से कम - क्योंकि Redis विखंडन का हिसाब नहीं दे सकता - लेकिन, एक छोटे से उत्तर के संदर्भ में, आपको ऐसा करना होगा, और अपने को फिर से शुरू करने की योजना शुरू करनी होगी सर्वर अक्सर।

कई ऑपरेटिंग सिस्टम और इन-मेमोरी डेटाबेस के साथ काम करने वाले अंगूठे का मेरा नियम है कि आपको अपनी वास्तविक मेमोरी 2x की आवश्यकता है, और मेमोरी का आकार लगभग 2 सप्ताह में स्थिर हो जाएगा।

हालाँकि, यह आपके वास्तविक आवंटन पैटर्न और आपके द्वारा उपयोग किए जा रहे मेमोरी एलोकेटर पर निर्भर करता है।

अभी, सर्वर के लिए मैंने जो सबसे अच्छा मेमोरी एलोकेटर पाया है, वह JEMalloc है। हम इसे एयरोस्पाइक पर लंबे समय तक स्मृति विखंडन को कम करने (लगभग हटाने) के लिए उपयोग करते हैं। JEMalloc में एक सुविधा है जो आपको एक मेमोरी "एरेना" (पूल) बनाने की अनुमति देती है, और किसी भी आवंटन पर, कौन सा पूल चुनें, इस प्रकार आपको आकार-प्रकार के आवंटन प्रदान करते हैं और समान मेमोरी आजीवन आवंटन का प्रबंधन करते हैं। जिस तरह के मामलों की आप चर्चा कर रहे हैं, यह हमारे लिए एक बड़ी जीत है।

Zend PHP इंजन इस संबंध में परिष्कृत है, क्योंकि इंजन के अंदर सभी आवंटन या तो प्रति-लेनदेन मेमोरी, या वैश्विक मेमोरी में हैं। लेनदेन के अंत में प्रति लेनदेन मेमोरी को एक-गिर-झपट्टा से मुक्त किया जाता है, और इस प्रकार बहुत कुशल हो सकता है।

यदि आप लिनक्स में हैं, तो कर्नेल मेमोरी एलोकेटर (क्लिब) ने कई ट्विस्ट और टर्न ले लिए हैं, और आप जिस संस्करण पर हैं, वह वास्तविक रूप से विखंडन की मात्रा निर्धारित करेगा, जैसा कि वास्तविक एप्लिकेशन पैटर्न होगा। उदाहरण के लिए, कुछ आबंटक बहुत बेहतर होते हैं जब आप थोड़े बढ़ रहे होते हैं, तो कुछ बहुत खराब होते हैं। अफसोस, यहां तक ​​कि अन्य रेडिस उपयोगकर्ताओं के साथ चर्चा करने का मतलब है कि आप किस ओएस का उपयोग कर रहे हैं और किस ओएस संस्करण के बारे में बात कर रहे हैं।

तथ्य यह है कि आप सर्वर को फिर से शुरू कर सकते हैं (दृढ़ता से) और अपनी मेमोरी को वापस पाने का मतलब रिसाव हो सकता है, लेकिन अधिक विखंडन की संभावना है।

  1. स्वैप को अस्वीकार करें (यह OOM से बेहतर है स्वैप के लिए, रेडिस के लिए)
  2. स्मरण शक्ति का कम होना
  3. एक शेड्यूल पर पुनरारंभ करें

समायोजन करके आप मेमोरी का आकार कैसे कम करेंगे maxmemory?
Nyxynyx
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.