स्वैप कैसे धीमा हो सकता है?


77

किसी तरह मैं 14 जीबी मेमोरी को स्वैप करने के लिए हुआ। अपराधी को मारने के बाद, मेरे पास फिर से मुफ्त मेमोरी है, इसलिए मैंने सोचा कि मैं फिर से महत्वपूर्ण डेटा ला सकता हूं । इसलिए 32 जीबी में से 5 जीबी का इस्तेमाल किया और 14 जीबी स्वैप स्पेस का इस्तेमाल किया, मैं भाग गया swapoff -a.... और 4 घंटे बाद लगभग आधा काम खत्म हो गया।

इसका मतलब यह है कि 1 एमबी / एस कम है, जबकि मैं आसानी से 200 एमबी / एस की नकल कर सकता हूं। मेरे स्वैप को एन्क्रिप्ट किया गया है, लेकिन सभी सामान्य विभाजन हैं और एईएस-नी के साथ यह ध्यान देने योग्य सीपीयू लोड की ओर जाता है (और स्वैप स्थान को भरने में केवल कुछ मिनट लगते हैं)। मैं देखता हूं कि अनुकूलन करने का कोई विशेष कारण नहीं है swapoff, लेकिन मुझे आश्चर्य है कि यह कैसे धीमा हो सकता है?


बस कुछ और डेटा जोड़ना: मेरी मुख्य मेमोरी 32 जीबी है और मेरे पास 4 हार्डडिस्क में से प्रत्येक पर 32 जीबी स्वैप स्पेस है (निश्चित रूप से एक ओवरकिल, लेकिन कौन परवाह करता है?)। पूरे स्वैप स्पेस को (डिक्रिप्ट और) 5 मिनट से कम समय में पढ़ा जा सकता है:

time -p sudo sh -c 'for i in /dev/mapper/cryptswap?; do md5sum $i & done; wait'
014a2b7ef300e11094134785e1d882af  /dev/mapper/cryptswap1
a6d8ef09203c1d8d459109ff93b6627c  /dev/mapper/cryptswap4
05aff81f8d276ddf07cf26619726a405  /dev/mapper/cryptswap3
e7f606449327b9a016e88d46049c0c9a  /dev/mapper/cryptswap2
real 264.27

एक विभाजन का एक हिस्सा पढ़ना यह सब पढ़ने की तुलना में धीमा नहीं हो सकता है। फिर भी इसके बारे में 1 / 10th पढ़ने में लगभग 100 गुना अधिक समय लगता है।

मैंने देखा कि swapoffदोनों के दौरान सीपीयू ज्यादातर बेकार था (शायद एक कोर का 10%) और इसलिए डिस्क (एलईडी द्वारा "मापा गया") थे। मैंने यह भी देखा कि स्वैप स्पेस एक के बाद एक बंद होते गए।


1
मुझे आश्चर्य है, क्या वही घटना तब होती है जब सिस्टम लोड किए गए पृष्ठों को वापस RAM में स्वयं द्वारा लोड करता है? उदाहरण के लिए, अगर मुझे डिस्क में एक सिस्टम सस्पेंड किया गया था और फिर शुरू किया गया था, तो सब कुछ स्वैप हो गया था और इसे वापस रैम में लोड किया जा रहा है। मुझे बहुत धीमा लगता है।
पेट्र पुडलक

क्या सभी स्वैप-डिवाइस एक ही प्राथमिकता के साथ सक्रिय हैं?
निल्स

@Petr Pudlák: डिस्क को निलंबित करना थोड़ा अलग है, यह बस स्वैप सामग्री को स्वैप क्षेत्र में एक खाली स्थान में लिखता है, और यह (और संयुक्त राष्ट्र का निलंबन) शायद बहुत तेज है। मैं कोशिश नहीं कर सकता क्योंकि यह एन्क्रिप्टेड स्वैप के साथ काम नहीं करता है।
Maaartinus 5

@ निल्स: हां, प्राथमिकता समान है और इसलिए डिस्क और उनके विभाजन हैं।
Maaartinus 5

जो इसे और अजीब बनाता है। इस मामले में स्वैप सभी डिस्क पर धारीदार है - यह बहुत तेज होना चाहिए। के iostat -d 5दौरान डिस्क पर कम आईओ दिखा था swapoff?
Nils

जवाबों:


53

सबसे पहले, आइए देखें कि आप अपनी हार्ड ड्राइव से क्या उम्मीद कर सकते हैं। आपकी हार्ड ड्राइव क्रमिक रूप से 200 एमबी / एस कर सकती है । जब आप कारक समय की तलाश करते हैं, तो यह बहुत धीमा हो सकता है । एक मनमाना उदाहरण लेने के लिए, सीगेट के आधुनिक 3TB डिस्क में से एक के लिए चश्मा पर एक नज़र डालें, ST3000DM001 :

  • अधिकतम निरंतर डेटा दर: 210 एमबी / एस

  • औसत पढ़ने की तलाश करें: <8.5 एमएस

  • प्रति सेक्टर बाइट्स: 4,096

यदि आपको कभी तलाश करने की आवश्यकता नहीं है, और यदि आपका स्वैप डिस्क के किनारे के पास है, तो आप अधिकतम दर = 210 एमबी / एस तक देखने की उम्मीद कर सकते हैं

लेकिन अगर आपका स्वैप डेटा पूरी तरह से खंडित है, तो सबसे खराब स्थिति में, आपको पढ़ने वाले प्रत्येक क्षेत्र की तलाश करनी होगी। इसका मतलब यह है कि आपको केवल ४ केबी हर ४. or एमबी या ४ केबी / ०.०० 4५ = ४ you० केबी / एस पढ़ने को मिलता है

तो बल्ले से सही, यह समझ से बाहर नहीं है कि आप वास्तव में हार्ड ड्राइव की गति के खिलाफ चल रहे हैं।


उस ने कहा, यह मूर्खतापूर्ण प्रतीत swapoffहोता है जो इतनी धीमी गति से चलेगा और पृष्ठों को क्रम से पढ़ना होगा, खासकर यदि वे जल्दी से लिखे गए थे (जो कि आदेश में निहित है)। लेकिन यह हो सकता है कि कर्नेल कैसे काम करे। उबंटू बग की रिपोर्ट # 486666 एक ही समस्या पर चर्चा करती है:

The swap is being removed at speed of 0.5 MB/s, while the
hard drive speed is 60 MB/s;
No other programs are using harddrive a lot, system is not under
high load etc.

Ubuntu 9.10 on quad core.

Swap partition is encrypted.
Top (atop) shows near 100% hard drive usage
  DSK | sdc | busy 88% | read 56 | write 0 | avio 9 ms |
but the device transfer is low (kdesysguard)
  0.4 MiB/s on /dev/sdc reads, and 0 on writes

उत्तर में से एक था:

It takes a long time to sort out because it has to rearrange and flush the
memory, as well as go through multiple decrypt cycles, etc. This is quite
normal

बग रिपोर्ट को अनसुलझा बंद कर दिया गया था।

मेल गोर्मन की पुस्तक " अंडरस्टैंडिंग द वर्चुअल वर्चुअल मेमोरी मैनेजर " थोड़ी पुरानी है, लेकिन इस बात से सहमत हैं कि यह एक धीमी गति से किया गया आवेदन है:

एक क्षेत्र को निष्क्रिय करने के लिए जिम्मेदार फ़ंक्शन, अनुमानित रूप से पर्याप्त है, कहा जाता है sys_swapoff()। यह फ़ंक्शन मुख्य रूप से अपडेट करने से संबंधित है swap_info_struct। प्रत्येक पृष्ठांकित-आउट पृष्ठ में पेजिंग का प्रमुख कार्य की जिम्मेदारी है try_to_unuse()जो है बेहद महंगा है।

2007 से लिनक्स-कर्नेल मेलिंग सूची में " स्वैग अप स्पीड " विषय पर थोड़ी अधिक चर्चा हुई है - हालांकि वे जिस गति की चर्चा कर रहे हैं, आप जो देख रहे हैं, उससे थोड़ा अधिक है।


यह एक दिलचस्प सवाल है जिसे शायद आमतौर पर नजरअंदाज कर दिया जाता है, क्योंकि swapoffशायद ही कभी इसका इस्तेमाल किया जाता है। मुझे लगता है कि यदि आप वास्तव में इसे नीचे ट्रैक करने के लिए चाहता था, पहला कदम अधिक ध्यान से अपने डिस्क उपयोग पैटर्न देखने का प्रयास कर किया जाएगा कि (शायद के साथ atop, iostatया और भी अधिक शक्तिशाली उपकरण की तरह perfया systemtap)। अत्यधिक तलाश करने वाली चीजें, छोटे I / O संचालन, निरंतर पुनर्लेखन और डेटा की गति, आदि हो सकते हैं।


5
बहुत बढ़िया स्पष्टीकरण। यह ध्यान दिया जाना चाहिए कि अधिकांश विखंडन को दरकिनार करना संभव है और स्वैप मेमोरी के बड़े वर्गों को कोर-डंपिंग द्वारा जल्दी से अधिक स्वैप मुक्त करना है: unix.stackexchange.com/questions/254202/ ...
ब्रैंडन ड्यूप्री

यह सिर्फ विखंडन / समय की तलाश नहीं है। मेरी स्वैप एसएसडी पर है और यादृच्छिक रीड बहुत तेज हैं, फिर भी स्वैपऑफ कमांड रास्ता धीमा है जितना कि इसे करना चाहिए और मेरा एसएसडी लोड लगभग 1% उपयोग पर बैठता है। मुझे संदेह है कि कर्नेल में या स्वैफ़ॉफ़ में कहीं सूची-चलना शामिल है (जो ~ 90-100% CPU का उपयोग करता है)। बेशक, अगर सभी काम क्रमिक रूप से किए जाते हैं और डिस्क की तलाश धीमी है, तो यह काफी बढ़ सकता है।
थॉमस गयोट-सायननेस्ट

33

मैं अपने लैपटॉप के साथ एक ही समस्या का सामना कर रहा हूं जिसमें एक SSD है ताकि समय की समस्या न हो।

मुझे एक वैकल्पिक स्पष्टीकरण मिला । यहाँ एक अंश है

अब यह जिस तरह से काम करता है, स्वैप स्वैप मेमोरी पेज में प्रत्येक स्वैप किए गए मेमोरी पेज को देखता है, और सभी प्रोग्रामों का उपयोग करने की कोशिश करता है। यदि यह उन्हें तुरंत नहीं मिल सकता है, तो यह प्रत्येक प्रोग्राम के पृष्ठ तालिकाओं को देखेगा जो उन्हें खोजने के लिए चल रहे हैं। सबसे खराब स्थिति में, यह विभाजन में हर स्वैप किए गए पृष्ठ के लिए सभी पृष्ठ तालिकाओं की जांच करेगा। यह सही है - एक ही पेज टेबल बार-बार चेक किया जाता है।

तो यह किसी और चीज के बजाय एक कर्नेल समस्या है।


नहीं, यह कर्नेल समस्या नहीं है IMHO। यह कैसे swapoffलागू किया गया है। जब स्वैप प्रक्रिया समाप्त हो जाती है तो उसमें इतना समय नहीं लगता।
Marki555

15
यह स्वैप में कार्यान्वयन के साथ एक समस्या है जो कर्नेल में है - इसलिए एक कर्नेल समस्या! आप देख सकते हैं कि आप strace swapoffबहुत ज्यादा यह सब करते हैं swapoffसिस्टम कॉल है।
निक क्रेग-वुड

1
मेरे पास 48GB रैम (32cores) वाला सर्वर है, 6 जीबी मुफ्त बग स्वैप का उपयोग 0.7GB किया गया था। swappiness = 10, इसे 0 बनाने की कोशिश की और यह भी देखा कि क्या होता है। अदला-बदली धीमी गति से जारी, शायद 30minutes उम्र लेती है। मेरे पास लगभग कोई लोड नहीं है और सीपीयू समान है, स्वैप प्रक्रिया की उम्मीद है जो एक सीपीयू 100% लेता है।
सोरिन

1
यह समस्या है कि स्वैप को कैसे लागू किया जाता है (कर्नेल में)। कर्नेल-देव में कुछ साल पहले बहुत बेहतर दृष्टिकोण के बारे में चर्चा हुई थी, लेकिन वे कहते हैं कि यह एक कोने का मामला है और इसे बदलने का प्रयास नहीं चाहते हैं।
मार्किस ५५

6
1 टीबी रैम (हाँ, टीबी) और 2 जीबी स्वैप (मूर्खतापूर्ण एसएपी की आवश्यकता) के साथ सर्वर पर स्वैप को 12 घंटे लग गए, जो कि 2 जीबी के 5% को मुफ्त (100% पर 1 सीपीयू कोर के साथ)।
मार्की ५५५

22

हाँ, swapoffतंत्र भयावह रूप से अक्षम है। वर्कअराउंड आसान है: स्वैप किए गए पृष्ठों पर पुनरावृति के बजाय, प्रक्रियाओं पर पुनरावृति। इस अजगर स्क्रिप्ट का उपयोग करें (मैं संबद्ध नहीं हूं):

git clone https://github.com/wiedemannc/deswappify-auto

ध्यान दें कि ऑपरेशन का डेमन मोड केवल डेस्कटॉप / लैपटॉप के लिए है जो अक्सर हाइबरनेट किए जाते हैं। मैं इसे एक सर्वर सिस्टम पर डेमॉन के रूप में नहीं चलाऊंगा - बस इसे अग्रभूमि में चलाएं, प्रतीक्षा करें जब तक यह रिपोर्ट न हो जाए कि यह कुछ प्रक्रियाओं का ध्यान रखता है तो इसे रोकें और कोशिश करें:

swapoff /dev/x

चूंकि अधिकांश पृष्ठ अब स्वैप और मेमोरी दोनों में मौजूद हैं, swapoffऐसा करने के लिए बहुत कम है और अब धधकते हुए तेजी से होना चाहिए (मैंने सैकड़ों एमबी / एस देखा)।

इतिहास खंड आगे

पूर्वोक्त पाइथन लिपि इस उत्तर के बाकी हिस्सों पर आधारित है, जो बदले में इस पुराने उत्तर को लंबे समय तक लिखे जाने का मेरा सुधार था । चूंकि स्क्रिप्ट बहुत अधिक सुरक्षित है, मैं केवल अपने उत्तर की रक्षा की अंतिम पंक्ति के रूप में कोशिश करने की सलाह देता हूं :

perl -we 'for(`ps -e -o pid,args`) { if(m/^ *(\d+) *(.{0,40})/) { $pid=$1; $desc=$2; if(open F, "/proc/$pid/smaps") { while(<F>) { if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ $start_adr=$1; $end_adr=$2; }  elsif(m/^Swap:\s*(\d\d+) *kB/s){ print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" }}}}}' | sort -Vr | head

यह हो सकता है 2 सेकंड चलाता है और वास्तव में कुछ नहीं करेंगे, बस शीर्ष 10 स्मृति खंडों (वास्तव में इसे और अधिक एक-लाइनर्स प्रिंट सूची; हाँ मैं है एक-लाइनर्स प्यार, बस आदेशों की जांच, जोखिम को स्वीकार, कॉपी और में पेस्ट अपने खोल; ये वास्तव में स्वैप से पढ़ा जाएगा)।

...Paste the generated one-liners...
swapoff /your/swap    # much faster now

मुख्य वन-लाइनर सुरक्षित है (मेरे लिए), सिवाय इसके कि वह बहुत अधिक / खरीद पढ़े।

आपकी मैन्युअल परीक्षा के लिए तैयार उप-कमांड सुरक्षित नहीं हैं । प्रत्येक कमांड स्वैप से मेमोरी सेगमेंट पढ़ने की अवधि के लिए एक प्रक्रिया लटकाएगा। तो यह ऐसी प्रक्रियाओं से असुरक्षित है जो किसी भी रुकावट को बर्दाश्त नहीं करती हैं। मेरे द्वारा देखी गई स्थानांतरण गति 1 गीगाबाइट प्रति मिनट के क्रम पर थी। (पूर्वोक्त अजगर लिपि ने उस कमी को दूर कर दिया)।

एक और खतरा सिस्टम पर बहुत अधिक मेमोरी दबाव डाल रहा है, इसलिए हमेशा की जांच करें free -m

यह क्या करता है?

for(`ps -e -o pid,args`) {

  if(m/^ *(\d+) *(.{0,40})/) { 
    $pid=$1; 
    $desc=$2; 

    if(open F, "/proc/$pid/smaps") { 

      while(<F>) { 

        if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ 
          $start_adr=$1; 
          $end_adr=$2; 
        } elsif( m/^Swap:\s*(\d\d+) *kB/s ){
          print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" 
        }
      }
    }
  }
}

इस पर्ल स्क्रिप्ट का आउटपुट gdbकमांड्स की एक श्रंखला है dump memory (range)जो स्मरण करने के लिए स्वैप किए गए पृष्ठों को याद करता है।

आउटपुट आकार से शुरू होता है, इसलिए आकार के आधार पर | sort -Vr | headशीर्ष 10 सबसे बड़े सेगमेंट प्राप्त करने के लिए इसे गर्त में पारित करना काफी आसान है । -Vसंस्करण संख्या-उपयुक्त छंटाई के लिए खड़ा है, लेकिन यह मेरी प्रयोजन के लिए काम करता है। मैं आंक नहीं सकता कि संख्यात्मक प्रकार का काम कैसे किया जाए।


आप यहाँ पर सांख्यिक प्रकार का प्रयोग करेंगेsort -t = -k 2n
स्टीफन चेज़लस

9
प्रक्रिया मेमोरी (कम से कम हाल की गुठली) पर नज़र रखने के लिए gdb का उपयोग करने की कोई आवश्यकता प्रतीत नहीं होती है। एक बस /proc/$pid/memसीधे खोल सकता है , तलाश कर सकता है और सीधे पढ़ सकता है। यहाँ PoC काफी हद तक आपके स्निपेट पर आधारित है: gist.github.com/WGH-/91260f6d65db88be2c847053c49be5ae इस तरह से प्रक्रिया को रोका नहीं जाता है, AFAIK को इससे होने वाले किसी भी खतरे का सामना नहीं करना चाहिए।
डब्ल्यूजीएच

10

स्वैपऑफ़ के दौरान, यदि एक इन-उपयोग स्वैप स्लॉट का पता चला है, तो कर्नेल पहले पृष्ठ में स्वैप होता है। फ़ंक्शन unuse_process () तब सभी पृष्ठ तालिका प्रविष्टियों को खोजने की कोशिश करता है जो सिर्फ स्वैप किए गए पृष्ठ के अनुरूप हैं और पृष्ठ तालिकाओं के लिए आवश्यक अद्यतन करता है। यह खोज संपूर्ण और बहुत समय लेने वाली है: यह प्रत्येक मेमोरी डिस्क्रिप्टर (संपूर्ण सिस्टम) पर जाती है और एक-एक करके इसकी पेज टेबल प्रविष्टियों की जांच करती है।

कृपया "लिनक्स कर्नेल 3 संस्करण को समझना" के पृष्ठ 724 को देखें।

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