Linux: сколько дискового ввода-вывода требуется, чтобы прочитать файл? Как минимизировать это? [Дубликат]

10

Согласно этой статье в стоге сена Facebook:

« Из-за того, как устройства NAS управляют метаданными каталога, размещение тысяч файлов в каталоге было крайне неэффективным, поскольку блок-карта каталога была слишком большой для эффективного кэширования устройством. Следовательно, для получения одиночное изображение. После уменьшения размеров каталогов до сотен изображений на каталог, получающаяся система, как правило, все равно будет выполнять 3 операции с дисками для извлечения изображения: одну для чтения метаданных каталога в память, вторую для загрузки индекса в память и третью. читать содержимое файла. "

Я предполагал, что метаданные и inode каталога файловой системы всегда будут кэшироваться в оперативной памяти ОС, а для чтения файла обычно требуется всего 1 дисковый ввод-вывод.

Является ли эта проблема «нескольких дисковых операций ввода-вывода для чтения одного файла» описанной в этой статье уникальной для устройств NAS, или же в Linux тоже есть такая же проблема?

Я планирую запустить сервер Linux для обслуживания изображений. В любом случае, я могу минимизировать количество дисковых операций ввода-вывода - в идеале, чтобы убедиться, что операционная система кэширует все данные каталогов и индексов в ОЗУ, а для каждого чтения файла потребуется не более 1 дискового ввода-вывода?

user9517
источник
1
Не ответ на вопрос, но вы всегда можете использовать Varnish (Facebook использует его), чтобы сохранить файлы в памяти. Таким образом, если один образ становится горячим (много запросов к одному и тому же файлу), дисковый ввод-вывод вообще не будет использоваться для его обслуживания
Darhazer - Varnish здесь не поможет, поскольку файловый кеш Linux (на который опирается Varnish) уже кэширует горячие файлы в памяти. Помещение Varnish перед Nginx для статической обработки файлов ничего не добавляет. Мой вопрос о том, когда файлы слишком велики / слишком много для кэширования в памяти. Я все еще хотел бы убедиться, что по крайней мере данные каталогов и inode кэшированы, чтобы уменьшить дисковый ввод-вывод до 1 на чтение
Многие файловые системы хранят индекс в каталоге, уменьшая количество запросов на один и значительно увеличивая вероятность попадания в кэш. Но это не вопрос программирования.
Бен Фойгт
Вы можете изменить размер блока файловой системы при его создании, например, mke2fs -b 32768чтобы сделать его 32 КБ. Однако это полезно, только если в этой файловой системе нет маленьких файлов.

Ответы:

5

У Linux такая же "проблема". Вот статья моего студента, опубликованная два года назад, где этот эффект показан на Linux. Несколько IO могут поступать из нескольких источников:

  • Поиск в каталоге на каждом уровне каталога пути к файлу. Может потребоваться прочитать индексный каталог и один или несколько блоков записи каталога.
  • Индод файла

В обычном шаблоне ввода-вывода кэширование действительно эффективно, и inode, каталоги и блоки данных размещаются таким образом, чтобы уменьшить количество запросов. Однако обычный метод поиска, который фактически используется всеми файловыми системами, плохо подходит для сильно рандомизированного трафика.

Вот несколько идей:

1) Помогают кеши, связанные с файловой системой. Большой кэш будет поглощать большинство чтений. Однако, если вы хотите поместить несколько дисков в машину, соотношение между диском и оперативной памятью ограничивает объем кешируемой памяти.

2) Не используйте миллионы маленьких файлов. Объедините их в более крупные файлы и сохраните имя файла и смещение в файле.

3) Поместите или кэшируйте метаданные на SSD.

4) И, конечно, используйте файловую систему, которая не имеет полностью анархического формата каталогов на диске. Readdir не должен занимать больше, чем линейное время, а прямой доступ к файлу в идеале просто логарифмическое время.

Хранение каталогов небольшого размера (менее 1000 или около того) не должно сильно помочь, потому что вам потребуется больше каталогов с необходимостью кэширования.

dmeister
источник
И, конечно же, используйте файловую систему, которая не имеет полностью архаичного формата каталогов на диске. Readdir не должен занимать больше, чем линейное время, а прямой доступ к файлу в идеале просто логарифмическое время.
Йоргенсен
Я добавил это к ответу как 4-й пункт
dmeister
@dmeister Хорошие вещи. +1
Магеллан
@dmeister Ваша ссылка мертва.
Дон Скотт
1

Это зависит от файловой системы, которую вы планируете использовать. Перед прочтением файловой системы данных:

  • Читать файл каталога.
  • Прочитайте инод вашего файла
  • Читайте сектора вашего файла

Если папка содержит огромное количество файлов, это большая угроза для кеша.


источник
Если вы перечисляете доступы ввода / вывода, было бы более интересно отделить выполненные действия open()от выполненных read(). На странице win.tue.nl/~aeb/linux/vfs/trail.html показана хорошая прогулка по различным концепциям ядра. (Может быть , это устаревший я не смог бы сказать?.)
ADL
0

Вы, вероятно, не сможете хранить все данные каталогов и узлов в оперативной памяти, поскольку у вас, вероятно, больше данных каталогов и узлов, чем в оперативной памяти. Вы также можете не захотеть, так как это ОЗУ лучше использовать для других целей; в вашем примере с изображением, вы бы предпочли, чтобы данные часто доступного изображения кэшировались в ОЗУ, чем запись каталога для нечасто доступного изображения?

Тем не менее, я думаю, что ручка vfs_cache_pressure используется для управления этим. «Когда vfs_cache_pressure = 0, ядро ​​никогда не будет восстанавливать dentries и inode из-за нехватки памяти, и это может легко привести к нехватке памяти».

Сэмюэл Эдвин Уорд
источник