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

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

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

Я использую ext3 и ntfs (я использую ntfs много!) Файловых систем с XUbuntu 11.10 x86.

5 Solutions collect form web for “Могу ли я настроить свою систему Linux для более агрессивного кэширования файловой системы?”

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

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

Сначала оптимизируйте часть load-stuff-from-storage-to-cache:

Вот моя настройка для HDD (убедитесь, что 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 (обычно пишите) и long slice_sync чтобы один процесс мог получить высокую пропускную способность (установите slice_sync на меньшее число, если вы slice_sync с ситуациями, когда несколько процессов ждут некоторых данных с диска параллельно). slice_idle всегда является компромиссом для жестких дисков, но настройка его где-то в диапазоне 3-20 должна быть в порядке в зависимости от использования диска и прошивки диска. Я предпочитаю использовать таргетинг для низких значений, но слишком низкая скорость будет разрушать вашу пропускную способность. Похоже, что quantum настройка сильно влияет на пропускную способность, но старайтесь держать ее как можно ниже, чтобы поддерживать латентность на разумном уровне. Установка слишком низкого quantum будет разрушать пропускную способность. Значения в диапазоне 3-8, похоже, хорошо работают с жесткими дисками. slice_sync задержка для чтения – ( 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 series):

 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 series кажется, что установка slide_idle в 0 дает наилучшую пропускную способность, но при настройке на 1 дает наилучшую (самую низкую) общую задержку.

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

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

В соответствии с blockdev показателями, которые я сделал, я бы не стал беспокоиться о том, чтобы читать дальше через 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 может отрицательно повлиять на производительность».

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

 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 и /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)& 

Во-первых, я НЕ рекомендую вам продолжать использовать NTFS, поскольку реализация ntfs в Linux будет проблемой производительности и безопасности в любое время.

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

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

Может быть, вы хотите попробовать 🙂

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

В 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.

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

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

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

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

vfs_cache_pressure

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

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

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

  • В чем разница между всеми параметрами и значением по умолчанию в настройках ядра?
  • Пределы дескриптора файла в / etc / system vs /etc/sysctl.conf vs /etc/security/limits.conf в Solaris
  • Проблема с Pernicious USB-stick stall. Возврат исправления обходного пути?
  • настройка flashcache
  • net.ipv4.ip_forward возвращает значение 0, даже если установлено в /etc/sysctl.conf
  • Изменение параметра Sysctl после каждой перезагрузки
  • Параметр sysctl для правильного ответа ARP
  • Параметры настройки ядра Linux +
  • Безвозмездный пакет ARP не отправляется, даже если «arp_notify» в sysctl установлен на 1 на OpenWRT
  • Требуется ли изменение sysctl для перезапуска процесса?
  • В чем разница между установкой пределов открытых файлов в файле /etc/sysctl.conf vs /etc/security/limits.conf?
  • Interesting Posts

    suid-root не влияет

    Как определяется определение типа файла по расширению имени файла в дополнение к спецификации XDG (mimeapps.list)

    Наследуются ли наследуемые переменные среды как переменные среды или переменные оболочки?

    почему существуют разные форматы для файла hosts между OpenSuSE и Ubuntu?

    Как проверить, содержит ли строка подстроку в тире или золе?

    FreeBSD systat не вычисляет скорость загрузки / total на wlan0

    Объединение двух частей вместе для создания единого сценария

    CentOS 7 Нет пакета … доступно

    Что читает / etc / iproute2 / rt_tables

    определить собственное время в Linux

    libpam-ck-connector, вызывающий apt-get to fail

    Как разбить вывод команды и назначить результат массиву, используя только одно выражение?

    Недавнее изменение приводит к тому, что Shift + Space ничего не делает

    Значения uniq первого столбца grep

    Как я могу установить файловую систему во время входа в систему?

    Linux и Unix - лучшая ОС в мире.