воскресенье, 6 сентября 2020 г.

Оптимизация Linux при использовании SSD

В прошлых статьях были описаны процедура обновления прошивки твердотельного накопителя Micron модели SSD 5200 MAX и шаблон Zabbix для контроля основных показателей его состояния. В этой статье пойдёт речь о том, какие дополнительные настройки Linux можно сделать для того, чтобы увеличить производительность системы при работе с твердотельными накопителями и увеличить срок службы самих накопителей.

Изменение планировщика ввода-вывода

По умолчанию Linux использует планировщик ввода-вывода cfq, который стремится упорядочить блоки данных так, чтобы уменьшить количество позиционирований головки с дорожки на дорожку диска. Для SSD это не имеет смысла, но приводит к задержке мелких операций ввода-вывода. Вместо планировщика cfq рекомендуется использовать планировщик deadline, который стремится сократить время ожидания выполнения каждой из операций ввода-вывода.

Изменить планировщик диска sda можно при помощи следующей команды:
# echo "deadline" > /sys/block/sda/queue/scheduler
Для того, чтобы выбранный планировщик диска применялся при загрузке системы, можно поставить пакет sysfsutils:
Оптимизация Linux при использовании SSD
# apt-get install sysfsutils
И прописать планировщик в файл /etc/sysfs.conf:
block/sda/queue/scheduler = deadline
Другой способ сделать изменения постоянными - создать файл /etc/udev/rules.d/60-ssd.rules со следующими правилами udev:
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="deadline"
Это правило для всех не вращающихся дисков с именем sd* будет устанавливать планировщик deadline.

Размер страницы

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

Например, по данным SMART размер логического сектора диска равен 512 байтам, а размер страницы равен 4096 байт:
# smartctl -i /dev/sda | grep Sector
Sector Sizes:     512 bytes logical, 4096 bytes physical
Убедиться в том, что ядро операционной системы Linux знает о размере физического сектора, можно следующим образом:
# cat /sys/block/sda/queue/physical_block_size 
4096

Увеличение резерва страниц

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

Часть общего объёма страниц диска закладывается в резерв. Напрмер, SSD объёмом 480 Гигабайт может иметь реальный объём 512 Гигабайт, а разница используется как раз для равномерного использования ресурса всех страниц.

Кроме того, в файловой системе может иметься свободное место, не занятое никакими данными. Это свободное место на SSD можно приобщить к резерву. Для этого операционная система может сообщать диску о неиспользуемых ею страницах при помощи ATA-команды TRIM. Для этого SSD должен поддерживать операцию TRIM, а файловая система должна поддерживать опцию монитрования discard.

Проверить наличие поддержки TRIM в SSD можно при помощи утилиты hdparm:
# hdparm -I /dev/sda | grep TRIM
           * Data Set Management TRIM supported (limit 8 blocks)
           * Deterministic read ZEROs after TRIM
Вторая строчка означает, что секторы, над которыми произведена команда TRIM, при попытке чтения будут возвращать нули. Другим возможным режимом может быть «Deterministic read after TRIM», когда при чтении возвращаются не нули, а какая-то другая всегда одинаковая последовательность данных.

Если на странице руководства man mount среди опций интересующей файловой системы имеется опция discard, то файловую систему можно перемонтировать с поддержкой этой опции.

Сначала посмотрим, с какими опциями смонтирована файловая система:
# findmnt /
TARGET SOURCE   FSTYPE OPTIONS
/      /dev/md0 ext4   rw,relatime,errors=remount-ro,data=ordered
Перемонтируем файловую систему, добавив к списку опций remount и discard:
# mount -o remount,rw,relatime,errors=remount-ro,data=ordered,discard /
Убеждаемся, что новая опция добавилась к текущему списку:
# findmnt /
TARGET SOURCE   FSTYPE OPTIONS
/      /dev/md0 ext4   rw,relatime,discard,errors=remount-ro,data=ordered
Чтобы отключить опцию discard, можно повторить процедуру перемонтирования, указав вместо опции discard опцию nodiscard.

Чтобы при перезагрузке операционная система монтировала файловую систему с опцией discard, нужно добавить её к списку опций монитрования в файле /etc/fstab. Например, строчка монтирования может выглядеть следующим образом:
UUID=324f1a70-5229-4376-afbb-eb274c8e60aa /               ext4    errors=remount-ro,discard 0       1
Чтобы сообщить диску о неиспользуемых секторах, которые были освобождены до включения опции discard, или при отключенной опции discard, можно воспользоваться командой fstrim:
# fstrim -v /
/: 146,6 MiB (153755648 bytes) trimmed
Кроме увеличения ресурса диска, использование TRIM и discard может приводить к увеличению скорости операций записи и чтения. Т.к. у контроллера есть в распоряжении много очищенных блоков, ему не придётся тратить время на их очистку для записи новых данных. При этом операция очистки блока может выполняться в фоновом режиме, когда SSD не занят выполнением операций чтения или записи.

Если на пути между файловой системой и диском имеются менеджер томов LVM или RAID-массив, то информация о неиспользуемых секторах может застревать в этих подсистемах и не доходить до SSD. Чтобы LVM сообщал о неиспользуемых секторах на нижележащий уровень, нужно в секции devices из файла конфигурации /etc/lvm/lvm.conf выставить следующую опцию:
issue_discards = 1
Убедиться в том, что TRIM корректно передаётся нижележащему хранилищу, можно при помощи команды:
# lsblk -D
Если TRIM поддерживается на всех уровнях, то в столбцах DISC-GRAN и DISC-MAX будут ненулевые значения:
NAME    DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda            0        4K       2G         0
└─sda1         0        4K       2G         0
  └─md0        0        4K       2G         0
sdb            0        4K       2G         0
└─sdb1         0        4K       2G         0
  └─md0        0        4K       2G         0
Если же TRIM не используется, то можно увидеть такую картину:
NAME                     DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                             0        0B       0B         0
├─sda1                          0        0B       0B         0
│ └─md0                         0        0B       0B         0
└─sda2                          0        0B       0B         0
  └─md1                         0        0B       0B         0
    ├─vg0-mon--disk             0        0B       0B         0
    └─vg0-mon--swap             0        0B       0B         0
sdb                             0        0B       0B         0
├─sdb1                          0        0B       0B         0
│ └─md0                         0        0B       0B         0
└─sdb2                          0        0B       0B         0
  └─md1                         0        0B       0B         0
    ├─vg0-mon--disk             0        0B       0B         0
    └─vg0-mon--swap             0        0B       0B         0
Возможны промежуточные варианты, когда файловая система отправляет операции TRIM на нижележащий уровень, но дальше эти операции не проходят.

Файловые системы в оперативной памяти

Т.к. интенсивный ввод-вывод снижает ресурс SSD, лучше избегать использовать SSD для хранения временных файлов. Например, раздел /tmp можно расположить в оперативной памяти. Временно это можно сделать при помощи такой команды:
# mount -t tmpfs tmpfs -o relatime,nodev,nosuid,noexec,mode=1777 /tmp
Если нужно ограничить максимальный размер файлов во временной файловой системе, к опциям noatime и nosuid можно добавить опцию size с указанием этого размера:
# mount -t tmpfs tmpfs -o relatime,nodev,nosuid,noexec,mode=1777,size=1G /tmp
Если временную файловую систему нужно монтировать автоматически при загрузке системы, нужно добавить в файл /etc/fstab соответствующую строчку:
tmpfs /tmp tmpfs relatime,nodev,nosuid,noexec,mode=1777,size=1G 0 0
Если файловая система уже не смонтирована, то теперь смонтировать её можно простой командоу:
# mount /tmp
Аналогичным образом можно монтировать другие временные файловые системы. Например:
tmpfs /var/tftp tmpfs relatime,nodev,nosuid,noexec,uid=tftp,gid=tftp,mode=0760,size=32M 0 0

Использованные материалы

Комментариев нет: