Linux: Bir dosyayı okumak için kaç disk G / Ç gerekir? Nasıl en aza indirilir? [çiftleme]


10

Facebook Haystack'taki bu makaleye göre :

" NAS cihazlarının dizin meta verilerini yönetme biçimi nedeniyle, dizinin binlerce eşlemesi dizinin bloğunun cihaz tarafından etkili bir şekilde önbelleğe alınamayacak kadar büyük olması nedeniyle binlerce dosya yerleştirmek son derece etkiliydi. Dizin boyutlarını dizin başına yüzlerce görüntüye düşürdükten sonra, sonuçta ortaya çıkan sistem genellikle bir görüntü almak için 3 disk işlemine neden olur: biri dizin meta verilerini belleğe okumak, ikincisi inode'u belleğe yüklemek için ve üçüncüsü dosya içeriğini okumak için. "

Dosya sistemi dizini meta verileri ve inode her zaman işletim sistemi tarafından RAM'de önbelleğe alınacağını ve okunan bir dosyanın genellikle sadece 1 disk IO gerektireceğini varsaymıştım.

Bu "NAS cihazlarına özgü bu makalede özetlenen" birden çok disk IO'su "sorunu mu yoksa Linux'ta da aynı sorun var mı?

Görüntüleri sunmak için bir Linux sunucusu çalıştırmayı planlıyorum. Herhangi bir şekilde disk IO sayısını en aza indirebilirim - ideal olarak işletim sisteminin RAM'daki tüm dizin ve inode verilerini önbelleğe aldığından ve her dosya okuduğunda yalnızca 1'den fazla disk GÇ gerektirmez mi?


1
Soruya bir cevap değil, ancak bellekteki dosyaları koruyan Varnish'i (Facebook bunu kullanır) her zaman kullanabilirsiniz. Bu şekilde, bir görüntü ısınırsa (aynı dosyaya çok fazla istek gelirse), disk IO bunu sunmak için hiç kullanılmayacaktır

Darhazer - Varnish, Linux dosya önbelleği (Varnish'in dayandığı) bellekteki sıcak dosyaları zaten önbelleğe aldığından burada yardımcı olmaz. Statik dosya sunumu için Verniği Nginx'in önüne koymak hiçbir şey eklemez. Benim sorum, dosyaların bellekte önbelleğe alınamayacak kadar büyük / çok fazla olması. Disk IO'yu okuma başına sadece 1'e düşürmek için en azından dizin verilerinin ve düğümlerin önbelleğe alındığından emin olmak istiyorum.

Birçok dosya sistemi, inode'u dizinde saklar, istek sayısını bir azaltır ve önbellek isabet şansını önemli ölçüde artırır. Ama bu bir programlama sorusu değil.
Ben Voigt

Dosya sistemini oluştururken, örneğin mke2fs -b 3276832k yapmak için ile blok boyutunu değiştirebilirsiniz . Ancak, bu yalnızca o dosya sisteminde küçük dosyalarınız yoksa kullanışlıdır.

Yanıtlar:


5

Linux aynı "soruna" sahiptir. İşte bir öğrencimin iki yıl önce yayınladığı ve etkinin Linux'ta gösterildiği bir çalışma. Çoklu ES'ler çeşitli kaynaklardan gelebilir:

  • Dosya yolunun her dizin düzeyinde dizin araması. Dizin inode ve bir veya daha fazla dizin giriş bloğunun okunması gerekebilir
  • Dosyanın inode'u

Normal IO modelinde önbellekleme gerçekten etkilidir ve inode, dizin ve veri blokları aramaları azaltacak şekilde tahsis edilir. Ancak, aslında tüm dosya sistemleri tarafından paylaşılan normal arama yöntemi, oldukça rasgele trafik için kötüdür.

İşte birkaç fikir:

1) Dosya sistemiyle ilgili önbellekler yardımcı olur. Büyük bir önbellek okumaların çoğunu emer. Ancak, bir makineye birden fazla disk koymak istiyorsanız, Disk / RAM oranı önbelleğe alınacak miktarı sınırlar.

2) Milyonlarca küçük dosya kullanmayın. Bunları daha büyük dosyalarda toplayın ve dosya adını ve ofseti dosya içinde saklayın.

3) Meta verileri bir SSD'ye yerleştirin veya önbelleğe alın.

4) Ve elbette tamamen anarşik bir disk dizini formatına sahip olmayan bir dosya sistemi kullanın. Bir readdir doğrusal zamandan daha fazla zaman almamalı ve doğrudan dosya erişimi ideal olarak sadece logaritmik zaman olmalıdır.

Dizinleri küçük tutmak (1000'den az) çok fazla yardımcı olmamalıdır çünkü önbelleğe alınması gereken daha fazla dizine ihtiyacınız olacaktır.


Ve elbette tamamen arkaik disk üzeri dizin formatına sahip olmayan bir dosya sistemi kullanın. Bir readdir doğrusal zamandan daha fazla zaman almamalı ve doğrudan dosya erişimi ideal olarak sadece logaritmik zaman olmalıdır.
jørgensen

Bunu cevaba 4. nokta olarak
ekledim

@dmeister İyi şeyler. +1
Magellan

@dmeister Bağlantınız öldü.
Don Scott

1

Bu, kullanmayı planladığınız dosya sistemine bağlıdır. Dosya veri sistemini okumadan önce:

  • Dizin dosyasını okuyun.
  • Dosyanızın inode'unu okuyun
  • Dosyanızın sektörlerini okuyun

Klasör çok sayıda dosya içeriyorsa, bu önbellekte büyük bir öneme sahiptir.


Eğer I / O erişimler listeleme iseniz, tarafından gerçekleştirilen bu ayırmak için daha ilginç olabileceğini open()tarafından gerçekleştirilen olanlardan read(). Win.tue.nl/~aeb/linux/vfs/trail.html sayfası , ilgili farklı Çekirdek kavramlarına rağmen güzel bir yol gösteriyor. (Belki eskimiş? Bunu söyleyemezdim.)
adl

0

Büyük olasılıkla RAM'den daha fazla dizin ve inode verisine sahip olduğunuzdan, tüm dizin ve inode verilerini RAM'de tutamazsınız. RAM'in başka amaçlar için daha iyi kullanılabileceği için de istemeyebilirsiniz; görüntü örneğinizde, sık erişilen bir görüntünün verilerinin, nadiren erişilen bir görüntünün dizin girişinden daha fazla RAM'de önbelleğe alınmasını istemez miydiniz?

Yani, vfs_cache_pressure düğmesi bunu kontrol etmek için kullanıldığını düşünüyorum . "Vfs_cache_pressure = 0 olduğunda, çekirdek bellek baskısı nedeniyle hiçbir zaman takma dişleri ve inodeları geri almayacaktır ve bu, bellek yetersiz durumlarına kolayca yol açabilir."

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.