Могу ли я настроить свою систему Linux для более агрессивного кэширования файловой системы?

119

Я не беспокоюсь ни об использовании оперативной памяти (так как у меня достаточно), ни о потере данных в случае случайного выключения (так как мое питание поддерживается, система надежна и данные не критичны). Но я много занимаюсь обработкой файлов и могу повысить производительность.

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

Я использую файловые системы ext3 и ntfs (я часто использую ntfs!) С XUbuntu 11.10 x86.

Иван
источник
6
Если у вас много оперативной памяти, вы заботитесь о производительности и не заботитесь о потере данных, просто скопируйте все свои данные на диск RAM и отправьте их оттуда, отбрасывая все обновления при сбое / завершении работы. Если это не сработает для вас, вам может понадобиться квалифицировать «достаточно» для оперативной памяти или насколько критичны данные.
Джеймс Янгман
1
@ Nils, компьютер - ноутбук, поэтому, я думаю, контроллер довольно обычный.
Иван
1
Один из способов повысить производительность - это пропустить срок службы данных. Просто отключите синхронизацию на диск, даже если некоторые приложения запрашивают синхронизацию. Это приведет к потере данных, если ваше устройство хранения данных когда-либо потеряет электричество. Если вы все равно хотите это сделать, просто выполните sudo mount -o ro,nobarrier /path/to/mountpointили настройте, /etc/fstabчтобы включить nobarrierдля любой файловой системы, которую вы готовы пожертвовать ради повышения производительности. Однако, если ваше устройство хранения данных имеет внутреннюю батарею, такую ​​как Intel 320 SSD, использование не nobarrierприводит к потере данных.
Микко Ранталайнен
1
Использование nobarrier больше не рекомендуется в Red Hat Enterprise Linux 6, поскольку отрицательное влияние барьеров записи на производительность незначительно (приблизительно 3%). Преимущества барьеров записи обычно перевешивают преимущества производительности при их отключении. Кроме того, опция nobarrier никогда не должна использоваться в хранилище, настроенном на виртуальных машинах. access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/…
Ивайло Бардаров
1
Два момента - 1) Существуют дистрибутивы Linux, основанные на Debian или Ubuntu, такие как Puppy Linux и AntiX Linux, и многие другие, которые помещают всю операционную систему в многоуровневые разделы ramdisk (например, AUFS или overlayfs) и управляют ими прозрачно. Очень быстро! - 2) Мы обнаружили в реальной конструкции очень большой системы, что использование большего объема кеша может снизить производительность. По мере увеличения скорости хранения (т. Е. SSD) оптимальный необходимый размер кэша уменьшается. Однако невозможно узнать, что это за размер, не экспериментируя на вашей конкретной системе. Если увеличение не работает, попробуйте уменьшить его.
DocSalvager

Ответы:

107

Улучшение производительности дискового кеша в целом - это больше, чем просто увеличение размера кеша файловой системы, если только вся ваша система не помещается в ОЗУ, в этом случае вам следует использовать ОЗУ ( tmpfsэто хорошо, потому что это позволяет вернуться к диску, если вам в некоторых случаях требуется ОЗУ) для хранения во время выполнения (и, возможно, сценарий initrd для копирования системы из хранилища на диск RAM при запуске).

Вы не сказали, является ли ваше устройство хранения SSD или HDD. Вот что я нашел работу для меня (в моем случае sdaэто HDD , установленный на /homeи sdbявляется SSD установлен на /).

Сначала оптимизируйте часть загрузки содержимого из хранилища в кэш:

Вот мои настройки для жесткого диска (убедитесь, что AHCI + NCQ включен в BIOS, если у вас есть переключатели):

echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda

Стоит отметить, что в случае с жестким диском высокая fifo_expire_async(обычно с записью) и большая длина slice_syncпозволяет одному процессу получать высокую пропускную способность (установите slice_syncменьшее значение, если вы сталкиваетесь с ситуациями, когда несколько процессов ожидают некоторые данные с диска параллельно). Это slice_idleвсегда компромисс для жестких дисков, но установка его в диапазоне от 3 до 20 должна быть приемлемой, в зависимости от использования диска и прошивки диска. Я предпочитаю ориентироваться на низкие значения, но слишком низкое значение ухудшит вашу пропускную способность. quantumУстановка , кажется, влияет на пропускную способность много , но попытаться сохранить это как можно меньше , чтобы сохранить время ожидания на разумном уровне. Установка quantumслишком низкого уровня приведет к разрушению пропускной способности. Значения в диапазоне 3-8, похоже, хорошо работают с жесткими дисками. Наихудшая задержка для чтения - ( quantum* slice_sync) + ( slice_async_rq*slice_asyncмс, если я правильно понял поведение ядра. Асинхронный режим в основном используется для записи, и, поскольку вы готовы отложить запись на диск, установите оба значения slice_async_rqи slice_asyncочень низкие значения. Однако установка slice_async_rqслишком низкого значения может остановить чтение, поскольку запись не может быть отложена после чтения. Моя конфигурация будет пытаться записать данные на диск в большинстве через 10 секунд после того, как данные были переданы ядру , но так как вы можете терпеть потерю данных о потере мощности и набор fifo_expire_asyncдля 3600000сказать , что 1 часы в порядке задержки на диск. Просто сохраняйте slice_asyncнизкий уровень, потому что в противном случае вы можете получить высокую задержку чтения.

Эта hdparmкоманда необходима для предотвращения потери AAM большей части производительности, которую позволяет AHCI + NCQ. Если ваш диск издает слишком много шума, пропустите это.

Вот моя установка для SSD (Intel 320 серии):

echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync

Здесь стоит отметить низкие значения для разных настроек среза. Наиболее важным параметром для SSD является slice_idleзначение 0-1. Установка его в ноль перемещает все решения о порядке в собственный NCQ, в то время как установка его в 1 позволяет ядру упорядочивать запросы (но если NCQ активен, аппаратная часть может частично изменить порядок ядра). Проверьте оба значения, чтобы увидеть разницу. Для Intel серии 320, это кажется , что установка slide_idleна 0дает наилучшую производительность , но установка его 1дает лучший ( самый низкий) общее время ожидания.

Для получения дополнительной информации об этих настройках см. Http://www.linux-mag.com/id/7572/ .

Теперь, когда мы настроили ядро ​​для загрузки содержимого с диска в кеш с ощутимой производительностью, пришло время настроить поведение кеша:

В соответствии с тестами, которые я сделал, я бы вообще не стал настраивать чтение вперед blockdev. Настройки ядра по умолчанию в порядке.

Установите для системы предпочтение замены файловых данных по сравнению с кодом приложения (это не имеет значения, если у вас достаточно ОЗУ для хранения всей файловой системы и всего кода приложения и всей виртуальной памяти, выделенной приложениями в ОЗУ). Это уменьшает задержку для переключения между различными приложениями по сравнению с задержкой для доступа к большим файлам из одного приложения:

echo 15 > /proc/sys/vm/swappiness

Если вы предпочитаете хранить приложения почти всегда в оперативной памяти, вы можете установить это значение равным 1. Если вы установите это значение равным нулю, ядро ​​вообще не поменяется местами, если только в этом нет крайней необходимости избегать OOM. Если у вас была ограниченная память и вы работали с большими файлами (например, редактирование HD-видео), то, возможно, имеет смысл установить это значение близко к 100.

Я сейчас (2017) предпочитаю вообще не иметь подкачки, если у вас достаточно оперативной памяти. Отсутствие свопинга обычно приводит к потере 200-1000 МБ ОЗУ на давно работающей настольной машине. Я готов пожертвовать этим, чтобы избежать задержки в худшем случае (замена кода приложения при заполнении ОЗУ). На практике это означает, что я предпочитаю обмен OOM Killer. Если вы разрешаете / нуждаетесь в обмене, вы также можете увеличить его /proc/sys/vm/watermark_scale_factor, чтобы избежать некоторой задержки. Я бы предложил значения от 100 до 500. Вы можете рассматривать эту настройку как торговую загрузку ЦП для более низкой задержки свопа. По умолчанию установлено значение 10, а максимально возможное значение равно 1000. Более высокое значение должно (в соответствии с документацией ядра ) привести к более высокой загрузке ЦП kswapdпроцессами и снижению общей задержки обмена.

Далее, скажите ядру, чтобы оно предпочитало хранить иерархию каталогов в памяти, а не содержимое файла, в случае, если необходимо освободить часть ОЗУ (опять же, если все умещается в ОЗУ, этот параметр ничего не делает):

echo 10 > /proc/sys/vm/vfs_cache_pressure

настройка vfs_cache_pressureнизкое значение имеет смысл, потому что в большинстве случаев ядру необходимо знать структуру каталогов, прежде чем оно сможет использовать содержимое файла из кэша, и слишком быстрая очистка кэша каталога сделает файловый кэш почти бесполезным. Если у вас много маленьких файлов, попробуйте пойти до 1 с этим параметром (моя система имеет около 150K 10-мегапиксельных фотографий и считается системой «много маленьких файлов»). Никогда не устанавливайте его в ноль, или структура каталогов всегда сохраняется в памяти, даже если системе не хватает памяти. Установка этого значения в большую имеет смысл, только если у вас есть только несколько больших файлов, которые постоянно перечитываются (опять же, пример HD-редактирования без достаточного объема ОЗУ был бы примером). Официальная документация по ядру говорит, что "

Исключение: если у вас действительно огромное количество файлов и каталогов, и вы редко касаетесь / читаете / выводите список всех файлов, значение которых vfs_cache_pressureпревышает 100, может быть целесообразным. Это применимо только в том случае, если у вас недостаточно ОЗУ и вы не можете сохранить всю структуру каталогов в ОЗУ и при этом все еще иметь достаточно ОЗУ для обычного файлового кэша и процессов (например, файловый сервер всей компании с большим количеством архивного содержимого). Если вы чувствуете, что вам нужно увеличить vfs_cache_pressureвыше 100, вы работаете без достаточного количества оперативной памяти. Увеличение vfs_cache_pressureможет помочь, но единственное реальное решение - получить больше оперативной памяти. Имея vfs_cache_pressureнабор для большого числа жертвует среднюю производительность для имеющих более стабильной работы в целом (то есть, вы можете избежать очень плохо наихудшего поведения случая , но иметь дело с худшей общей производительностью).

Наконец, скажите ядру использовать до 99% ОЗУ в качестве кэша для записи и дайте указание ядру использовать до 50% ОЗУ перед тем, как замедлить процесс записи (по умолчанию для dirty_background_ratiois 10). Предупреждение: лично я бы не стал этого делать, но вы утверждали, что у вас достаточно оперативной памяти и готовы потерять данные.

echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio

И скажите, что задержка записи в 1 час - это нормально, даже если вы начнете записывать что-то на диск (опять же, я бы этого не делал):

echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs

Если вы добавите все это /etc/rc.localи включите в конце следующее, все будет в кеше как можно скорее после загрузки (делайте это только в том случае, если ваша файловая система действительно помещается в ОЗУ):

(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

Или немного более простая альтернатива, которая может работать лучше (только для кеша, /homeи /usrделайте это только в том случае, если ваша /homeи /usrдействительно умещается в ОЗУ):

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Микко Ранталайнен
источник
3
Хорошо информированный и в целом гораздо лучший ответ, чем принятый! Этот недооценен ... Я думаю, что большинство людей просто хотят простые инструкции, не удосужившись понять, что они на самом деле делают ...
Владимир Пантелеев
2
@Phpdevpad: Кроме того, в вопросе говорилось: «Меня не беспокоит использование ОЗУ [...]» - я не думаю, что какое-либо устройство Maemo подходит.
Микко Ранталайнен
1
Разве noop или дедлайн не являются лучшим планировщиком для SSD?
rep_movsd
1
@rep_movsd Я использую только твердотельные накопители Intel, но, по крайней мере, эти накопители все еще достаточно медленные, чтобы улучшить общую производительность с помощью более интеллектуальных планировщиков, таких как CFQ. Я предполагаю, что если ваш SSD-накопитель может обрабатывать более 100K случайных операций ввода-вывода в секунду, использование noop или дедлайна имело бы смысл даже с быстрым ЦП. Под «быстрым процессором» я подразумеваю нечто, имеющее как минимум несколько ядер 3 ГГц, доступных только для ввода-вывода.
Микко Ранталайнен
1
Вы также можете прочитать об этих настройках vm из документации по ядру vm .
Joeytwiddle
16

Во-первых, я НЕ РЕКОМЕНДУЮ вам продолжать использовать NTFS, так как реализация ntfs в Linux может привести к проблемам с производительностью и безопасностью в любое время.

Есть несколько вещей, которые вы можете сделать:

  • использовать некоторые новые фс, такие как ext4илиbtrfs
  • попробуйте поменять свой io планировщик, например bfq
  • выключить своп
  • использовать какой-то автоматический предзагрузчик, такой как preload
  • использовать что-то вроде systemdпредварительной загрузки при загрузке
  • ... и кое-что еще

Может быть, вы хотите попробовать :-)

Феликс Ян
источник
1
Я уже полностью перешел от NTFS к ext4, оставив единственный раздел NTFS системным разделом Windows. Но это доставило мне много неудобств, и я вернулся к файловой системе NTFS в качестве основного раздела данных (где я храню все свои документы, загрузки, проекты, исходный код и т. Д.). Я не перестаю переосмысливать структуру разделов и рабочий процесс (чтобы использовать меньше Windows), но сейчас отказ от NTFS кажется нереальным вариантом.
Иван
Если вам также нужно использовать свои данные в Windows, NTFS может быть единственным вариантом. (доступно много других опций, если вы можете использовать Windows как виртуальную машину внутри Linux)
Феликс Ян
1
Краткое изложение этих предполагаемых проблем NTFS было бы полезно.
underscore_d
2
NTFS в Linux в значительной степени приемлема, за исключением производительности. Учитывая, что вопрос был конкретно об улучшении производительности файловой системы, NTFS должна быть в первую очередь.
Микко Ранталайнен
Несмотря на то, btrfsчто недавно была разработана файловая система, я бы избегал этого, если требуется производительность. Мы эксплуатируем в противном случае идентичных системы с btrfsи ext4файловыми системами и ext4победы в реальном мире , с большим отрывом ( btrfsкажется, требует около ого процессорного времени на ext4потребности того же уровень производительности и вызывает больше дисковых операции для одной логической команды). В зависимости от рабочей нагрузки, я бы предложил ext4, jfsили xfsдля любой работы, требующей высокой производительности.
Микко Ранталайнен
8

Читать дальше:

В 32-битных системах:

blockdev --setra 8388607 /dev/sda

В 64-битных системах:

blockdev --setra 4294967295 /dev/sda

Записать за кешем:

echo 100 > /proc/sys/vm/dirty_ratio

Это будет использовать до 100% вашей свободной памяти в качестве кэша записи.

Или вы можете сделать все возможное и использовать tmpfs. Это актуально, только если у вас достаточно оперативной памяти. Вставь это /etc/fstab. Замените 100G объемом физической памяти.

tmpfs /mnt/tmpfs tmpfs size=100G,rw,nosuid,nodev 0 0

Затем:

mkdir /mnt/tmpfs; mount -a

Затем используйте / mnt / tmpfs.

Оле Танге
источник
5
3 ГБ или 2 ТБ для чтения? действительно? Вы даже знаете, что делают эти опции?
Cobra_Fast
1
@Cobra_Fast Вы знаете, что это значит? Я действительно понятия не имею, и мне сейчас интересно.
syss
3
@ssss настройки чтения в режиме чтения сохраняются в виде количества «блоков» памяти, а не байтов или битов. Размер одного блока определяется во время компиляции ядра (поскольку блоки readahead являются блоками памяти) или в некоторых случаях во время создания файловой системы. Обычно, однако, 1 блок содержит 512 или 4096 байтов. Смотрите linux.die.net/man/8/blockdev
Cobra_Fast
6

Вы можете установить размер упреждающего чтения с помощью blockdev --setra sectors /dev/sda1, где секторы - это размер, который вы хотите в 512-байтовых секторах.

psusi
источник
2

Моя настройка убийцы очень проста и очень эффективна:

echo "2000" > /proc/sys/vm/vfs_cache_pressure

Объяснение из документации ядра :

vfs_cache_pressure

Управляет тенденцией ядра восстанавливать память, которая используется для кэширования объектов каталогов и узлов.

При значении по умолчанию vfs_cache_pressure = 100 ядро ​​будет пытаться восстанавливать dentries и inode с «справедливой» скоростью в отношении восстановления pagecache и swapcache. Уменьшение vfs_cache_pressure приводит к тому, что ядро ​​предпочитает сохранять кэш-память dentry и inode. Когда vfs_cache_pressure = 0, ядро ​​никогда не будет восстанавливать dentries и inode из-за нехватки памяти, и это может легко привести к нехватке памяти. Увеличение значения vfs_cache_pressure выше 100 заставляет ядро ​​предпочитать восстановление зубных рядов и инодов.

vfs_cache_pressure в 2000 приводит к тому, что большая часть вычислений происходит в ОЗУ и очень поздние записи на диск.

SLM
источник
4
Установка vfs_cache_pressureслишком высокого (я бы посчитал 2000слишком высоким) приведет к ненужному доступу к диску даже для простых вещей, таких как списки каталогов, которые должны легко помещаться в кэш. Сколько у вас оперативной памяти и что вы делаете с системой? Как я писал в своем ответе, использование высокого значения для этого параметра имеет смысл, например, для редактирования HD-видео с ограниченным объемом ОЗУ.
Микко Ранталайнен,
2
Обратите внимание, что ссылка на документацию продолжается: « Значительное увеличение vfs_cache_pressure за пределы 100 может оказать негативное влияние на производительность . При восстановлении кода требуются различные блокировки, чтобы найти свободные каталоги и объекты inode. При vfs_cache_pressure = 1000 он будет искать в десять раз больше свободных объектов, чем там. находятся."
Микко Ранталайнен
1

Не связано с кэшированием записи, но связано с записью:

  • Для системы ext4 вы можете полностью отключить ведение журнала

    Это уменьшит количество операций записи на диск для любого конкретного обновления, но может привести к тому, что файловая система будет в нестабильном состоянии после неожиданного завершения работы, требующего fsck или хуже.

Чтобы остановить чтение диска от запуска записи на диск:

  • Смонтировать с релевантностью или опцией noatime

    Когда вы читаете файл, метаданные «время последнего доступа» для этого файла обычно обновляются. noatimeОпция будет отключить это поведение. Это уменьшает ненужные записи на диск, но у вас больше не будет этих метаданных. Некоторые дистрибутивы (например, Manjaro) приняли это как значение по умолчанию для всех разделов (возможно, для увеличения срока службы более ранних моделей твердотельных накопителей).

    relatimeобновляет время доступа реже, в соответствии с эвристикой, которая помогает поддерживать приложения, которые используют atime. Это значение по умолчанию в Red Hat Enterprise Linux.

Другие опции:

  • В комментариях выше, Микко поделился возможностью монтажа с опцией nobarrier . Но Ивайло процитировал RedHat, который предостерегает против этого. Насколько сильно вы хотите эти дополнительные 3%?
joeytwiddle
источник