В Linux JBD - это независимый интерфейс журналирования блочных устройств в файловых системах ext3, ext4 и OCFS2 (Oracle Cluster File System). OCFS2 начиная с Linux 2.6.28, а также ext4 используют "форк" JBD известный как JBD2.
В показаниях top|iotop интерфейс журналирования блочных устройств JBD (Journaling Block Device) появляется в виде процесса под именем jbd2 или sda2-8, который проявляет активность по умолчанию с интервалом в 5 сек.:
https://www.kernel.org/doc/Documentation/filesystems/ext4.txt commit=nrsec (*) Ext4 can be told to sync all its data and metadata every 'nrsec' seconds. The default value is 5 seconds. This means that if you lose your power, you will lose as much as the latest 5 seconds of work (your filesystem will not be damaged though, thanks to the journaling). This default value (or any low value) will hurt performance, but it's good for data-safety. Setting it to 0 will have the same effect as leaving it at the default (5 seconds). Setting it to very large values will improve performance.
jbd2 (sda2-8) часто обращается к диску для журналирования изменений и из-за того, что процесс jbd2 (sda2-8) постоянно дергает диск, многие предпочитают завышать параметр "commit=nrsec" в опциях монтирования файловой системы надеясь на прирост производительности.
Собственно в описаниях параметра и сказано "Setting it to very large values will improve performance.", что установка очень больших значений позволит повысить производительность, но разумеется в ущерб производительности данных.
Но, не всё так просто, как может показаться на первый взгляд и для того чтобы точно знать какое именно значение "commit=nrsec" поможет увеличить производительность, мы должны чётко себе представлять как в Linux работает JBD (Journaling Block Device) интерфейс журналирования блочных устройств.
Какие данные журналирует JBD/JBD2
Официальная документация гласит:
https://www.kernel.org/doc/Documentation/filesystems/ext4.txt data=journal All data are committed into the journal prior to being written into the main file system. Enabling this mode will disable delayed allocation and O_DIRECT support. data=ordered (*) All data are forced directly out to the main file system prior to its metadata being committed to the journal. data=writeback Data ordering is not preserved, data may be written into the main file system after its metadata has been committed to the journal.
Что в переводе означает:
- data=journal - В журнал заносятся все данные про изменения в файловой системе перед записью в главную файловую систему. Включение этого режима отключает "отложенное размещение" и поддержку O_DIRECT.
- data=ordered - Метаданные заносятся в журнал до записи в главную файловую систему с предварительной группированием метаданных и блоков данных в единое целое называемое транзакцией (transaction).
- data=writeback - Метаданные, без их группирования, заносятся в журнал после записи в главную файловую систему.
По факту режим data=journal является самым медленным, но существует мнение, что в отдельных тестах при одновременной записи и одновременном чтении, скорость чтения была выше чем при других режимах журналирования, и, что мол этот режим больше всего подходит там где часто выполняются одновременные чтение и запись - опять же, не факт.
Вполне возможно скорость чтения при data=journal будет чуть выше, чем скорость записи, но при условии если результат чтения не зависит от результата записи. Например чтение PHP скрипта, который обращается к БД с целью записи - в таком случае прирост скорости чтения нивелируется понижением скорости записи.
Опытным путём установлено, что для веб-сервера режим data=writeback является самым производительным.
Commit в JBD/JBD2
Как JBD (JBD2) совершает запись в журнал? Журналирование транзакции представляет собой процесс регистрации одного или нескольких атомарных операций файловой системы в журнале на диске. Только после успешного совершения (Commit) транзакции (transaction), операция может считаться полной и гарантируется, что даже в случае краха, эти операции смогут быть восстановлены файловой системой.
Commit выполняется в 8 основных этапов. Основной функцией, которая совершает Commit-ы является journal_commit_transaction(). Когда пришло время добавить данные в журнал, журнал уже находится в рабочем состоянии (T_RUNNING), в момент же совершения записи статус изменяется на T_LOCKED, а все новые потоки данных переходят в режим ожидания до завершения уже начатой транзакции.
В момент завершения транзакции предпринимаются попытки очистить все буферы, принадлежащие зарезервированным спискам (t_reserved_list), а также освободить память, избавившись от буферов сидя на списке контрольных точек (t_checkpoint_list). Интервал Commit-ов регулируется параметром "commit=nrsec".
Информация по Commit в JBD/JBD2 (Journaling Block Device) на kernel.org довольно скудная, а краткое описание приведённое выше является частичным переводом статьи Journalling Block Device (JBD) Linux article, где можно почитать подробнее про Commit в JBD (JBD2)
Как оптимизировать работу Journaling Block Device
Самым популярным способом оптимизации JBD (JBD2) является параметр commit=nrsec, установка которого в очень высокие значения может улучшить производительность - это даже согласно оф. документации. Но это не тот случай, когда "кашу маслом не испортишь"!
Прежде чем шаманить параметрами файловой системы, нужно взять во внимание общее состояние системы, т.е. как минимум знать общий объём физической (оперативной) памяти и скорость доступа к диску.
Например, мы знаем, что между commit-ами JBD/JBD2 хранит данные о изменении ФС в памяти (в буферах, кэше), а значит:
- При завышенных значениях параметра commit=nrsec объём данных накапливаемых между длинными commit-ами будет значительно выше, чем между короткими промежутками;
- Большие порции данных при длинных commit-ах будут записываться на жесткий диск дольше, вызывая при этом ощутимый интервал I/O Wait если скорость доступа к диску относительно мала;
- Затяжной commit отнимет больше памяти, чем короткий.
Следовательно, если у нас слабый диск, мало РАМы, и, мы хотим избежать длительного I/O Wait при "коммитах", то не стоит устанавливать очень большие значения для commit=nrsec.
Хорошим ходом к оптимизации будет понижение I/O приоритета на commit операции:
journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the highest priority) which should be used for I/O operations submitted by kjournald2 during a commit operation. This defaults to 3, which is a slightly higher priority than the default I/O priority.
По умолчанию journal_ioprio=3, большее значение понижает приоритет:
iotop -o -d 3 Total DISK READ: 549.51 K/s | Total DISK WRITE: 281.53 K/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 232 be/7 root 0.00 B/s 816.68 B/s 0.00 % 5.93 % [jbd2/sda2-8] 1858 be/4 mysql 816.68 B/s 235.28 K/s 0.00 % 4.60 % mysqld --~-port=3306 2126 be/4 dja 138.77 K/s 0.00 B/s 0.00 % 4.34 % php-cgi ....
Не лишними также будут и следующие параметры (нет времени на перевод, переводите сами;-):
journal_checksum Enable checksumming of the journal transactions. This will allow the recovery code in e2fsck and the kernel to detect corruption in the kernel. It is a compatible change and will be ignored by older kernels. journal_async_commit Commit block can be written to disk without waiting for descriptor blocks. If enabled older kernels cannot mount the device. This will enable 'journal_checksum' internally. noauto_da_alloc Many broken applications don't use fsync() when replacing existing files via patterns such as fd = open("foo.new")/write(fd,..)/close(fd)/ rename("foo.new", "foo"), or worse yet, fd = open("foo", O_TRUNC)/write(fd,..)/close(fd). If auto_da_alloc is enabled, ext4 will detect the replace-via-rename and replace-via-truncate patterns and force that any delayed allocation blocks are allocated such that at the next journal commit, in the default data=ordered mode, the data blocks of the new file are forced to disk before the rename() operation is committed. This provides roughly the same level of guarantees as ext3, and avoids the "zero-length" problem that can happen when a system crashes before the delayed allocation blocks are forced to disk.
Ну, и разумеется смена режима журналирования на writeback, удаление некоторых излишних функций, а также финальная правка /etc/fstab:
При использовании твердотельных SSD (solid-state drive) накопителей ещё можно применить "tune2fs -o discard /dev/sda1".
А раз уж мы затронули тему оптимизации, то ещё вскользь упомянём и про такие навязчивые процессы как kswapd0 и pdflush (ещё ака flush-8:0):
Ссылки по теме:
- Ext3 Filesystem Documentation - kernel.org
- Frequently Asked Questions - Ext4
- Journaling block device - Wikipedia, the free encyclopedia
- Сравнение файловых систем — Википедия