Насколько эффективен fast_commit для ext4 и почему он не включен по умолчанию

  • Автор:

fast-commit-ext4-000.pngLinux, как и любая современная система, постоянно развивается, получает новые функции и возможности. Одной из таких возможностей стала появившаяся в ядре 5.10 опция fast_commit для файловой системы ext4, которая обещала, в некоторых случаях, до двукратного прироста производительности операций записи. Звучит многообещающе, только вот никто из разработчиков дистрибутивов первого эшелона пока не спешит радовать своих пользователей новинкой. Почему? Давайте разбираться.

Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Немного теории

Начнем с того, что многие современные интернет ресурсы, включая околотехнические, работают по принципу "слышал звон, но не знаю где он". Они просто рассказывают как включить fast_commit, вновь и вновь приводя краткое описание, из чего может сложиться впечатление что это некая "киллер-фича" которая нужна всем и каждому. Но так ли это на самом деле?

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

Начнем с базового устройства. Файловая система представляет собой особым образом организованное дисковое пространство, разделенное на логические единицы хранения данных (кластеры, блоки и т.д.). Однако недостаточно просто поместить данные файла в блоки, тем более, что файл не обязательно будет занимать непрерывную последовательность блоков, он может быть раскидан по всему диску вперемешку с данными иных файлов. Кроме того, в файловой системе могут существовать и более высокоуровневые объекты, например, жесткие ссылки, и тогда содержимое блока может принадлежать сразу нескольким файлам. Также следует каким-то образом учитывать дополнительные атрибуты: владельца, права доступа и т.д. и т.п.

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

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

Как-то все уже не очень просто, а ведь мы еще не углублялись в подробности. А что будет если в самый разгар дисковых операций произойдет сбой? Скажем, пропадет электропитание?

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

Старожилы могут помнить, в давние времена, когда основной системой была FAT или ext2, аварийное отключение в разгар операций записи могло не только повредить данные, но и вывести из строя саму файловую систему, не говоря уже о потерянных файлах, пустых файловых указателях и прочих "радостях жизни".

Можно ли как-то избежать подобной ситуации? Можно. Если мы вернемся на наш склад, то добавим в накладные два поля: товар получил и товар выдал. Взяв с полки товар, кладовщик отмечает, что он его получил, а отдав заказчику ставит вторую пометку - выдал. И только после того, как будут установлены обе пометки, операция считается завершенной. Здесь мы вплотную подходим к понятию транзакции - операции или набора операций, которые могут быть либо полностью выполнены, либо полностью откачены, промежуточного состояния транзакции быть не может.

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

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

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

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

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

Вот здесь мы и подошли к fast_commit - это новый, оптимизированный механизм фиксации транзакций в файловой системе, он не заменяет, а дополняет существующие механизмы и в ряде случаев способен дать существенный прирост производительности операций записи. Т.е. мы более быстро фиксируем транзакции и позволяем повысить производительность в том случае, если она упирается в журнал. Никаких чудес от данной функции ожидать не стоит, ваш медленный ноутбучный диск на 5400 rpm от нее летать не начнет.

Что показывают тесты?

Согласно тестам fast_commit весьма и весьма эффективен, но мы не будем принимать все на веру и организуем собственное тестирование, для этого будем использовать диск Samsung 860 EVO 250 ГБ SSD M.2 и операционную систему Ubuntu 22.04 LTS с ядром 5.15.0-37. В качестве тестов мы будем использовать приложения Fsmark и Dbench из штатного репозитория ОС.

BenchmarkConfigfast_commit offfast_commit on
Fsmark Local, 8 threads 1562 Files/sec 7006 Files/sec
Dbench Local, 2 procs 27.8 MB/sec 264.64 MB/sec
Dbench Local, 10 procs 97.58 MB/sec 493.34 MB/sec

Результаты действительно отличные. Здесь даже не двукратный прирост, а увеличение производительности в разы, а то и на порядок. Скажем. в тесте Dbench Local, 10 procs мы просто уперлись в производительность диска. Но почему тогда в дистрибутивах fast_commit не включен и новые файловые системы создаются без этой опции?

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

fast-commit-ext4-001.pngИ что мы видим? Да ничего, никакого эффекта от включения fast_commit для повседневных задач и нагрузок нет. Почему так? Как раз об этом мы много говорили выше, fast_commit эффективен в тех случаях, когда производительность записи упирается в журнал, повседневные задачи не испытывают необходимости в гарантированной записи на диск, их вполне устраивает кеширование и буферизация записи, поэтому вызывать fsync нет необходимости и fast_commit оказывается бесполезен.

Собственно, поэтому разработчики и не спешат включать fast_commit по умолчанию, это эффективный инструмент, но только для вполне определенного узкого круга задач, в остальных случаях он не нужен. А каждая дополнительная функция файловой системы - это потенциальный источник сбоев или уязвимостей. Так что здесь тоже все логично. Те, кто знает и понимает зачем им нужен fast_commit - включат его, остальным это не нужно.

От теории к практике

Но довольно теории, давайте перейдем к практике, каким образом можно включить fast_commit для файловой системы ext4? В первую очередь в момент ее создания, при форматировании раздела используйте команду:

mkfs.ext4 -O fast_commit /dev/sdb1

В нашем случае мы отформатировали раздел /dev/sdb1.

Проверить включен ли fast_commit можно командой:

tune2fs -l /dev/sdb1 | grep fast_commit

Пустой вывод означает, что функция не подключена, иначе вы должны увидеть что-то похожее:

fast-commit-ext4-002.pngА как быть, если файловая система уже создана? Обращаем внимание, что fast_commit - это не опция монтирования, это функция операционной системы. Добавить ее в существующую ФС можно, внеся изменения в суперблок, но для этого файловая система должна быть отмонирована. В противном случае вы рискуете полной потерей данных.

Для отмонтирования используйте команду:

umount /dev/sdb1

Затем добавьте нужную опцию:

tune2fs -O fast_commit /dev/sdb1

Теперь можно снова монтировать файловую систему на постоянное место. Если ваша файловая система прописана в fstab то достаточно простой команды:

mount -a

Если вы хотите включить fast_commit для корневой файловой системы, то вам потребуется загрузиться с Live-CD и внести изменения в суперблок с него.

Ну и еще один насущный вопрос: а как обстоят дела с совместимостью? Что будет если мы включим fast_commit, а потом подключим этот диск к системе с ядром ниже, чем 5.10? Ничего страшного, в файловых системах ext строго соблюдается принцип обратной совместимости, мы можем даже смонтировать ext4, как ext2 и прочитать оттуда все данные. Поэтому никаких проблем совместимости от включения fast_commit у вас не возникнет.

Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Поддержи автора и новые статьи будут выходить чаще:

Поддержи проект!

Или подпишись на наш Телеграм-канал: Подпишись на наш Telegram-канал



Loading Comments