लिनक्स फाइल सिस्टम कैश से एक विशिष्ट फ़ाइल को गिराएं?


23

मुझे पता है कि मैं लिनक्स फाइल सिस्टम कैश से सब कुछ छोड़ सकता हूं , लेकिन क्या सिर्फ एक विशिष्ट फाइल को छोड़ने का एक तरीका है? या किसी फ़ाइल को कैश होने से रोकें? या एक प्रक्रिया बताएं जो इसे लिखी गई किसी भी फाइल को कैश न करें?

मेरे पास एक ऐसी प्रक्रिया है जो बहुत कम फ़ाइलों को पढ़ती है और एक बड़ी फ़ाइल लिखती है। मैं डिस्क फाइल्स से बचने के लिए कैश में छोटी फाइलों को रखना चाहता हूं, और मुझे बड़ी फाइल को कैशिंग करने की परवाह नहीं है।


1
इनाम के बारे में, मैं शीर्षक प्रश्न में विशेष रूप से दिलचस्पी रखता हूं: कैश से एक विशिष्ट फ़ाइल को गिराना (जैसा कि इसे पहले स्थान पर रोकने से रोकने के लिए)।
गाइल्स का SO- बुराई से रोकना '

जवाबों:


21

संभावित विधि # 1 - F_DROP_CACHES

मुझे 2012 से एक विधि मिली, जो इस मेल थ्रेड में लिनक्स कर्नेल के लिए प्रस्तावित पैच की चर्चा करती है जिसका शीर्षक है: Re: [RFC Patch] fs: प्रति फ़ाइल ड्रॉप कैश लागू करें

अंश

Cong> यह प्रति फ़ाइल ड्रॉप कैश लागू करने का एक मसौदा पैच है।

दिलचस्प। तो क्या मैं इसे एक प्रक्रिया से बाहर कर सकता हूं? मैं एक SysAdmin हूं, इसलिए मेरा POV सिस्टम के दबाव में प्रदर्शन समस्याओं को देखने, खोजने और ठीक करने से है।

Cong> It introduces a new fcntl command  F_DROP_CACHES to drop  
Cong> file caches of a specific file. The reason is that currently  
Cong> we only have a system-wide drop caches interface, it could  
Cong> cause system-wide performance down if we drop all page caches  
Cong> when we actually want to drop the caches of some huge file.

मैं कैसे बता सकता हूं कि किसी फ़ाइल द्वारा कितना कैश का उपयोग किया जाता है? और व्यस्त सिस्टम पर चलने पर इसका प्रदर्शन प्रभाव क्या है? और यह पैच हमें क्या खरीदता है क्योंकि मैं वीएम को पहले से ही सिस्टम को दबाव में आने के बाद पहले ही कैश छोड़ देना चाहिए ...

कांग> नीचे इस पैच के लिए छोटा परीक्षण मामला है:

थ्रेड में एक टेक्सेकेस और वास्तविक पैच दोनों शामिल हैं लिनक्स कर्नेल के भीतर कई फाइलें जो कि एक अतिरिक्त फ़ंक्शन को fs/drop_caches.cकहते हैं drop_pagecache_file(struct file *filp)। यह फ़ंक्शन तब फ्रंटेंड टूल के fnctl.cमाध्यम से, कमांड के माध्यम से पहुंच योग्य है F_DROP_CACHES। यह मामला इस फ़ंक्शन को कॉल करता है:

file_drop_caches(filp, arg);

जो दिए गए फ़ाइल से जुड़े सभी कैश को छोड़ने का काम करता है। फ़ाइल से include/linux/mm.h:

void file_drop_caches(struct file *filp, unsigned long which);
तो इसका उपयोग किया जा सकता है?

मुझे इस बात का कोई सबूत नहीं मिला कि इस पैच ने कभी मुख्य लिनक्स कर्नेल कोड रिपॉजिटरी में अपना रास्ता बनाया, इसलिए यह विकल्प उपलब्ध प्रतीत होगा, केवल तभी जब आप लिनक्स कर्नेल को अपने आप को फिर से तैयार करने के लिए तैयार हों।

संभावित विधि # 2 - dd का उपयोग करना

उसी धागे में, एक अन्य उपयोगकर्ता पूरी तरह से अलग कार्यप्रणाली का उल्लेख करता है जो उपयोग करता है dd

निम्नलिखित उस ईमेल का अंश है

यह उपयोगी कार्यक्षमता है। हालांकि यह पहले से ही प्रदान नहीं किया गया है POSIX_FADV_DONTNEED? यह कार्यक्षमता एक साल पहले GNU dd (8.11) में जोड़ी गई थी

यहाँ उस पैच से उदाहरण दिए गए हैं:
  • पूरी फ़ाइल के लिए कैश छोड़ने की सलाह दें

     $ dd if=ifile iflag=nocache count=0
    
  • पूरी फ़ाइल के लिए ड्रॉप कैश सुनिश्चित करें

     $ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
    
  • फ़ाइल के भाग के लिए कैश छोड़ें

     $ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
    
  • स्ट्रीम डेटा केवल पढ़ने के लिए आगे कैश का उपयोग कर

     $ dd if=ifile of=ofile iflag=nocache oflag=nocache
    
इसका परीक्षण किया जा रहा है

मैं 100% सकारात्मक नहीं था कि इसका परीक्षण कैसे करूं लेकिन मैं निम्नलिखित दृष्टिकोण के साथ आया हूं।

  1. एक 100MB फ़ाइल बनाओ

    $ dd if=/dev/urandom of=sample.txt bs=100M count=1
    
  2. ट्रेस फ़ाइल का उपयोग करके fatrace

    $ sudo fatrace | grep sample.txt
    
  3. चलाएं topताकि हम मेमोरी उपयोग, नोट राशि मुफ्त में देख सकें।

    $ top
    
  4. खुली फ़ाइल, अब मुफ्त मेमोरी की मात्रा नोट करें। fatraceफ़ाइल पर ध्यान दें sample.txt

    $ cat sample.txt > /dev/null
    
  5. फ़ाइल को मेमोरी से ड्रॉप करें, अब फ्री मेमोरी की मात्रा नोट करें। के आउटपुट पर ध्यान दें fatrace

    $ sudo dd of=/home/saml/tst/162600/sample.txt \
        oflag=nocache conv=notrunc,fdatasync count=0
    

उदाहरण

टर्मिनल # 1 में:
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s

$ ls -l sample.txt 
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
टर्मिनल # 2 में:
$ top
...
KiB Mem:   7968336 total,  6900956 used,  1067380 free,   267080 buffers
...
टर्मिनल # 3 में:
$ sudo fatrace | grep sample.txt
अब फ़ाइल खोलें sample.txt, और रैम की मात्रा पर ध्यान दें। टर्मिनल # 1 में।
$ cat sample.txt > /dev/null
टर्मिनल # 2 में:
KiB Mem:   7968336 total,  7011896 used,   956440 free,   267336 buffers
fatraceटर्मिनल # 3 के आउटपुट पर ध्यान दें :
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
अब टर्मिनल # 4 में रैम से फाइल निकालें:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
    oflag=nocache conv=notrunc,fdatasync count=0
fatraceटर्मिनल # 2 के आउटपुट पर ध्यान दें :
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
टर्मिनल # 3 में RAM पर ध्यान दें:
KiB Mem:   7968336 total,  6908364 used,  1059972 free,   267364 buffers

तो ऐसा लगता है कि रैम में फ़ाइल द्वारा खपत की गई सभी को मुक्त कर दिया गया है।

संभावित विधि # 3 - अजगर-सनक

@Frostchutz द्वारा एक टिप्पणी के लिए धन्यवाद, एक और उपकरण है, पायथन स्क्रिप्ट, जिसका नाम [pyadvise][4]उपरोक्त ddविधियों की तुलना में बहुत सरल इंटरफ़ेस प्रदान करता है । यह स्क्रिप्ट एक ही posix_fadvise(2)इंटरफ़ेस का उपयोग करती है ।

उदाहरण
$ sudo pyadvise --help
Usage: 
    pyadvise [options] [FILE]..

Options:
  -h, --help        show this help message and exit
  -w, --willneed    The specified files will be accessed in the near future
  -s, --sequential  The application expects to access the specified files
                    sequentially (with lower offsets read before higher ones)
  -d, --dontneed    The specified files will not be accessed in the near
                    future
  -r, --random      The specified files will be accessed in random order
  -o, --noreuse     The specified files will be accessed only once. Under
                    Linux, this operation is a no-op; see contrib/copyfileobj-
                    fadvise.py in the python-fadvise source tree for an
                    example on how to achieve approximately the same effect
  -n, --normal      Indicates that the application has no advice to give about
                    its access pattern for the specified files. If no advice
                    is given for an open file, this is the default assumption
  -v, --verbose     Explain what is being done

और यदि हम उपरोक्त परीक्षण को दोहराते हैं और इसके pyadviseस्थान पर उपयोग करते हैं dd:

$ pyadvise -d /home/saml/tst/162600/sample.txt

मैंने देखा कि जब मैं उपयोग करता था तो रैम में एक समान गिरावट देखी गई थी dd


ddमेरे लिये कार्य करता है। मैंने अपने आप को chris-lamb.co.uk/projects/python-fadvise के साथ समाप्त किया जो कि अधिक स्पष्ट आदेश में एक ही बात है।
फ्रॉस्ट्सचुट्ज़

@frostschutz - बहुत अच्छा। मैंने यह तब तक नहीं सुना था जब तक कि गिल्स ने नहीं पूछा कि क्या किसी को पता है कि यह चैट में कैसे किया जाता है। python-fadviseबहुत आसान है, मैंने एक उदाहरण दिखाया है dd
SLM

अजगर स्क्रिप्ट का लिंक प्रश्न के मुख्य भाग में स्थानांतरित किया जाना चाहिए। टिप्पणियाँ बिना ट्रेस के गायब हो सकती हैं। एक एडिट सबसे बुरी तरह अभी भी इतिहास में रहेगा। कहा जा रहा है कि, Google खोज आसानी से मिल जाती है, इसलिए यह कोई बड़ी बात नहीं है।
फहीम मीठा

यहां तक ​​कि यह सूडो के बिना काम करने लगता है, इसलिए जो कोई भी फ़ाइल (बिना लिखित अनुमति के) देख सकता है, उसका कैश गिरा दिया जा सकता है, यह दिलचस्प है।
फ्रॉस्ट्सचुट्ज़

1
अभी os.posix_fadvise()पायथन के मानक लाइब्रे में है।
kawing-chiu

3

@ Geekosaur के उत्तर का विस्तार करते हुए आप O_DIRECTLD_PRELOAD और यहां कार्यक्रम का उपयोग करके इसे मजबूर कर सकते हैं: http://arighi.blogspot.com/2007/04/how-to-bypass-buffer-cache-in-linux.html

यह कोड O_DIRECTसभी फाइलों के लिए मजबूर करता है। हालाँकि, __do_wrap_openआप में कुछ और strncmp तर्क जोड़कर चुनिंदा O_DIRECT लागू कर सकते हैं।

डिस्क्लेमर: मैंने इसका परीक्षण नहीं किया है।


2

आप O_DIRECTझंडे के साथ अलग-अलग फाइलें खोल सकते हैं (देखें man 2 open) - उस मैनपेज के NOTES अनुभाग को ध्यान से पढ़ें , और विचार करें कि क्या आप भी चाहते हैं / जरूरत है O_SYNC


1
खैर, मेरी प्रक्रिया है cat, और मैं इसे फिर से नहीं लिखूंगा। :) मैं एक कमांड-लाइन टूल या /proc/sysनॉब की उम्मीद कर रहा था ।
जे हैकर

2
इससे भी बदतर, मुझे संदेह है कि आपको वास्तव में मतलब है कि आप पुनर्निर्देशन का उपयोग कर रहे हैं, इसलिए आपकी प्रक्रिया शेल है। मैं openध्वज से अलग इसे नियंत्रित करने के लिए एक प्रति-फ़ाइल तरीका नहीं जानता ; आपको वास्तव में इसे करने के लिए एक कार्यक्रम लिखने की आवश्यकता होगी। ( cat -uकेवल stdioबफ़रिंग को अक्षम करता है, ओएस बफ़रिंग को नहीं।)
गीकॉउसर

-2

यदि आप किसी फ़ाइल को हमेशा O_SYNC का उपयोग करने के लिए बाध्य करना चाहते हैं, तो आप इसे इसके साथ विस्तारित विशेषताओं में चिह्नित कर सकते हैं chattr +S $file:

आदमी बकवास:

जब 'एस' विशेषता सेट के साथ एक फाइल को संशोधित किया जाता है, तो डिस्क पर परिवर्तन सिंक्रोनाइज़ किए जाते हैं; यह फ़ाइलों के सबसेट पर लागू 'सिंक' माउंट विकल्प के बराबर है।

O_SYNC डेटा + मेटाडेटा को डिस्क बफ़र्स को लिखने के लिए बाध्य करता है, लेकिन यह अभी भी पेज कैश से गुजरता है। O_DIRECT पेज कैश को बायपास करता है।

लेकिन यह ध्यान रखें कि इसे O_DIRECT के साथ खोलना प्रदर्शन के लिए हानिकारक होगा, अगर बड़ी फ़ाइल जिसे अभी जोड़ा जा रहा है वह अंतर छोटा हो सकता है। लेकिन अगर बड़ी फाइल को यादृच्छिक स्थानों पर फिर से लिखा गया है तो O_DIRECT प्रदर्शन पर एक बहुत बड़ी हिट होगी, यहां तक ​​कि यह भी ध्यान में रखते हुए कि यह कैश में है यह संभवतः कैश की कुछ छोटी फ़ाइलों को पढ़ सकता है।

यदि आपके पास वहाँ सभी छोटी फ़ाइलों को रखने के लिए रैम है, तो आप समस्या को दूसरे तरीके से देख सकते हैं। सुनिश्चित करें कि छोटी फाइलें हमेशा RAM में होती हैं, फिर मैं उन्हें tmpfs में कॉपी करने का सुझाव दूंगा :

tmpfs कर्नेल आंतरिक कैश में सब कुछ डालता है और इसमें मौजूद फ़ाइलों को समायोजित करने के लिए बढ़ता और सिकुड़ता है


chattr +Sजैसी बात नहीं है O_DIRECT, यह वैसी ही है O_SYNCO_DIRECTकारण पढ़े जाते हैं कि कैश नहीं किया जाए (जो कि यह सवाल है), और लिखते हैं कि बिना किसी गारंटी के, बफरिंग न करें। O_SYNCकारण केवल लिखते हैं कि बफरिंग नहीं की जानी चाहिए।
गाइल्स का SO- दुष्ट होना बंद हो '

@ आप सही हैं, मैंने सवाल पढ़ा और डिस्क को फ्लश करने के बारे में सोचा जैसा मैंने पहले किया था। और एक और सूक्ष्म, लेकिन इस मामले में महत्वपूर्ण है, O_DIRECT और O_SYNC के बीच का अंतर, O_DIRECT पेज कैश को बायपास करता है, लेकिन O_SYNC नहीं, यह डेटा (और मेटाडेटा) को डिस्क में फ्लश करने के लिए मजबूर करता है, लेकिन यह पेज कैश और कैश से गुजरता है वहाँ रखा जाता है स्पीडअप पढ़ता है। क्या मुझे अपने उत्तर में O_SYNC के लिए O_DIRECT बदलना चाहिए क्योंकि यह गलत प्रतिज्ञान के साथ नहीं रहने देना चाहिए?
जॉर्ज नेरिन

यह सवाल एक बड़ी फाइल रखने के बारे में पूछता है कि यह कैश से बाहर लिखा गया है। मुझे लगता है कि इसे O_DIRECT के साथ खोलना प्रदर्शन के लिए हानिकारक होगा, और यदि बड़ी फ़ाइल को अभी-अभी जोड़ा जा रहा है तो अंतर छोटा हो सकता है। लेकिन अगर बड़ी फाइल को यादृच्छिक स्थानों पर फिर से लिखा गया है तो O_DIRECT प्रदर्शन पर एक बहुत बड़ी हिट होगी, यहां तक ​​कि इस बात को भी ध्यान में रखते हुए कि यह संभवत: कैश से कुछ छोटी पढ़ी गई फाइलों को निकाल सकती है।
जॉर्ज नेरिन

बदलने O_DIRECTसे O_SYNCआपका उत्तर आंतरिक रूप से सुसंगत हो जाएगा, लेकिन फिर भी प्रश्न को गलत मानते हुए।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.