Linux dosya sistemi önbelleğinden belirli bir dosya bırakılsın mı?


23

Her şeyi Linux dosya sistemi önbelleğinden bırakabileceğimi biliyorum , ancak yalnızca belirli bir dosyayı bırakmanın bir yolu var mı? Veya bir dosyanın önbelleğe alınmasını engellemek mi? Veya bir işlemin yazdığı herhangi bir dosyayı önbelleğe almamasını söyler misiniz?

Çok sayıda küçük dosya okuyan ve büyük bir dosya yazan bir işlemim var. Disk aramalarını önlemek için küçük dosyaları önbellekte tutmak istiyorum ve büyük dosyayı önbelleğe almayı umursamıyorum.


1
Ödül ile ilgili olarak, özellikle şu soruya ilgi duyuyorum: belirli bir dosyayı önbellekten bırakmak (ilk etapta oraya gitmesini engellemek yerine).
Gilles 'SO- kötü olmaktan'

Yanıtlar:


21

Potansiyel Yöntem # 1 - F_DROP_CACHES

2012'den itibaren Linux çekirdeğine önerilen bir yamayı bu posta başlığında tartışan bir yöntem buldum: Re: [RFC Patch] fs: dosya başına bırakma önbellekleri uygulama .

alıntı

Cong> Bu, dosya başına bırakılan önbellekleri uygulama taslağıdır.

İlginç. Peki bunu bir sürecin dışından yapabilir miyim? Ben bir SysAdmin'im, bu yüzden POV'm sistem baskı altındayken performans sorunlarını fark etmekten, bulmaktan ve düzeltmekten geliyor.

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.

Bir dosya tarafından ne kadar önbellek kullanıldığını nasıl öğrenebilirim? Meşgul bir sistemde çalışırken bunun performansa etkisi nedir? Ve bu yama bize ne kazandırıyor, çünkü sistem mem baskısı altına girdiğinde VM'nin önbellekleri atması gerektiğini düşünüyorum.

Cong> Aşağıda bu yama için küçük bir test durumu var:

İş parçacığı, Linux çekirdeğindeki birkaç dosyaya bir test çantası ve gerçek düzeltme eki olarak fs/drop_caches.cadlandırılan ek bir işlev ekler drop_pagecache_file(struct file *filp). Bu işleve, ön uç aracından, fnctl.ckomut aracılığıyla erişilebilir F_DROP_CACHES. Bu durumda bu işlevi çağırır:

file_drop_caches(filp, arg);

Bu, verilen dosyayla ilişkili tüm önbelleklerin atılmasını sağlar. Dosyadan include/linux/mm.h:

void file_drop_caches(struct file *filp, unsigned long which);
Yani bu kullanılabilir mi?

Bu yamanın ana Linux çekirdek kod deposuna girdiğine dair hiçbir kanıt bulamadım, bu nedenle bu seçenek yalnızca Linux çekirdeğini kendiniz yeniden derlemeye istekli olmanız durumunda mümkün olacaktı.

Potansiyel Yöntem # 2 - dd kullanma

Aynı iş parçacığında, başka bir kullanıcı yararlanan tamamen farklı bir metodolojiden bahseder dd.

Aşağıdakiler bu e-postadan alıntıdır

Bu kullanışlı bir işlevdir. Zaten ile sağlanan olmasa da POSIX_FADV_DONTNEED? Bu işlev bir yıl önce GNU gg'ye (8.11) eklendi .

İşte bu yamadan örnekler:
  • Tüm dosya için önbellek bırakma önerisi

     $ dd if=ifile iflag=nocache count=0
    
  • Tüm dosya için önbellek bırakmayı sağlama

     $ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
    
  • Dosyanın bir kısmı için önbellek bırak

     $ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
    
  • Sadece ileriye dönük önbelleği kullanarak veri akışı

     $ dd if=ifile of=ofile iflag=nocache oflag=nocache
    
Test etmek

Nasıl test edileceği konusunda% 100 olumlu değildim ama aşağıdaki yaklaşıma ulaştım.

  1. 100 MB dosya yapmak

    $ dd if=/dev/urandom of=sample.txt bs=100M count=1
    
  2. dosya erişimlerini izleme fatrace

    $ sudo fatrace | grep sample.txt
    
  3. çalıştırın, topböylece bellek kullanımını izleyebiliriz, not miktarını ücretsiz.

    $ top
    
  4. dosyayı açın, şimdi boş hafıza miktarını not edin. Not fatraceDosyanın sample.txt.

    $ cat sample.txt > /dev/null
    
  5. dosyayı bellekten bırakın, şimdi boş belleği not alın. Çıktısına dikkat edin fatrace.

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

Örnek

Terminal 1'de:
$ 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
Terminal 2'de:
$ top
...
KiB Mem:   7968336 total,  6900956 used,  1067380 free,   267080 buffers
...
Terminal # 3'te:
$ sudo fatrace | grep sample.txt
Şimdi dosyayı açın ve sample.txtRAM miktarını not edin. # 1 numaralı terminalde.
$ cat sample.txt > /dev/null
Terminal 2'de:
KiB Mem:   7968336 total,  7011896 used,   956440 free,   267336 buffers
fatrace3 numaralı terminalin çıkışına dikkat edin :
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
Şimdi dosyayı # 4'teki terminalden RAM'den çıkarın:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
    oflag=nocache conv=notrunc,fdatasync count=0
fatrace2 numaralı terminalin çıkışına dikkat edin :
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
3 numaralı terminaldeki RAM’e dikkat edin:
KiB Mem:   7968336 total,  6908364 used,  1059972 free,   267364 buffers

Öyle görünüyor ki, RAM tarafından tüketilenlerin tümü boşaldı.

Potansiyel Yöntem # 3 - python-fadvise

@Frostchutz tarafından yapılan bir yorum sayesinde [pyadvise][4], yukarıdaki ddyöntemlerden çok daha basit bir arayüz sağlayan bir Python betiği başka bir araç var . Bu script aynı posix_fadvise(2)arayüzü kullanır.

Örnek
$ 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

Ve yukarıda testi ve kullanımını tekrar eğer pyadviseyerine dd:

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

RAM’de, eskisi gibi tüketildiğindeki aynı düşüşü fark ettim dd.


ddbenim için çalışıyor. Daha bariz bir şekilde aynı şeyi yapan kendimi chris-lamb.co.uk/projects/python-fadvise ile bitirdim .
frostschutz

@frostschutz - çok havalı. Gilles, bunu sohbette nasıl yapılacağını bilen var mı diye sormadan bunu duymamıştım. python-fadviseçok daha kolay, gösteren bir örnek ekledim dd.
slm

Python betiği için bağlantı, sorunun ana gövdesine taşınmalıdır. Yorumlar iz bırakmadan kaybolabilir. Bir düzenleme en kötü ihtimalle hala tarihte kalacaktır. Bunu söyledikten sonra, bir Google araması kolayca bulur, o kadar da önemli değil.
Faheem Mitha

Sudo olmadan da çalışıyor gibi görünüyor, bu yüzden bir dosyayı görebilen (yazma izni olmasa bile) önbelleği düşebilir, bu ... ilginç.
frostschutz

1
Orada os.posix_fadvise()şimdi Python'un standart libray içinde.
kawing-chiu


2

Dosyaları ayrı ayrı O_DIRECTbayrakla açabilirsiniz (bkz. man 2 open) - bu sayfanın NOTES bölümünü dikkatlice okuyun ve isteyip istemediğinizi de düşünün O_SYNC.


1
Şey, benim işlemim catve yeniden yazmak istemem. :) Bir komut satırı aracı veya /proc/systopuzu umuyordum .
Jay Hacker

2
Bundan daha kötüsü, yönlendirme kullandığınız anlamına geldiğinden şüpheleniyorum, bu yüzden işleminiz kabuk. openBayrağı bir kenara bırakıp kontrol etmenin dosya başına bir yolunu bilmiyorum ; Bunu yapmak için gerçekten bir program yazmanız gerekir. ( cat -uyalnızca stdioarabelleğe alma
işlemini engeller

-2

Bir dosyayı her zaman O_SYNC kullanmaya zorlamak istiyorsanız, genişletilmiş özniteliklerde aşağıdaki şekilde işaretleyebilirsiniz chattr +S $file:

erkek sohbet

'S' özniteliği ayarlanmış bir dosya değiştirildiğinde, değişiklikler diske aynı anda yazılır; bu, dosyaların bir alt kümesine uygulanan 'sync' mount seçeneğine eşdeğerdir.

O_SYNC, veri + meta verilerini disk arabelleklerine yazılmaya zorlar, ancak yine de sayfa önbelleğinden geçer. O_DIRECT, sayfa önbelleğini atlar.

Ancak, onu O_DIRECT ile açmanın performansa zarar vereceğini unutmayın; eğer büyük dosya eklenmişse fark küçük olabilir. Fakat eğer büyük dosya rastgele yerlerde yeniden yazılmışsa, O_DIRECT performans açısından çok büyük bir etki yaratacaktır, hatta önbelleğe almasının küçük okuma dosyalarının bir kısmını önbellekten çıkarması ihtimalini bile göz önünde bulundurabilir.

Tüm küçük dosyaları orada tutmak için ram varsa, soruna başka bir şekilde yaklaşabilirsiniz. Küçük dosyaların her zaman ram olduğundan emin olun, sonra bunları tmpfs'e kopyalamanızı öneririm :

tmpfs her şeyi çekirdek iç önbelleklerine yerleştirir ve içerdiği dosyaları barındırmak için büyür ve küçülür.


chattr +Saynı şey değildir O_DIRECT, bu aynı şeydir O_SYNC. O_DIRECTnedenler önbelleğe alınmamasını (bu sorunun neyle ilgili olduğunu) okur ve garanti edilmeksizin tamponlanmamasını yazar. O_SYNCSadece neden yazıyor tamponlu olmamak.
Gilles 'SO- kötülük yapmayı bırak'

@Gilles haklısın, ben soruyu okudum ve daha önce yaptığım gibi verileri diske atmayı düşündüm. Ve başka bir ince, ancak bu durumda önemli olan, O_DIRECT ve O_SYNC, O_DIRECT arasındaki fark sayfa önbelleğini atlar, ancak O_SYNC değil, verileri (ve meta verileri) diske temizlemeye zorlar, ancak sayfa önbelleğinden geçirir ve orada okur hızlandırmak için tutulur. Yanlış bir onaylama ile kalmaması için cevabımdaki O_SYNC için O_DIRECT'i değiştirmeli miyim?
Jorge Nerín

Bu soru, önbellekten silinen büyük bir dosyayı saklamayı ister. Bence O_DIRECT ile açmak performansa zarar verir ve eğer büyük dosya sadece eklendiyse bu fark küçük olabilir. Ancak eğer büyük dosya rastgele yerlerde yeniden yazılmışsa, O_DIRECT, küçük okuma dosyalarının bir kısmını önbellekten çıkarabileceğini göz önüne alarak bile performans üzerinde çok büyük bir etki yaratacaktır.
Jorge Nerín

Değişen O_DIRECTiçin O_SYNCCevabınız içten tutarlı kılacak, ama yine de yanlış soruyu dikkate.
Gilles 'SO- kötülük yapmayı bırak'
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.