Создание большого количества грязных страниц блокирует синхронную запись

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

Вот тест, реализованный на SLES11 SP4. Сервер имеет огромную память, что позволяет ему создавать 4 ГБ грязных страниц.

> dd if=/dev/zero of=todel bs=1048576 count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 3.72657 s, 1.2 GB/s
> dd if=/dev/zero of=zer oflag=sync bs=512 count=1  
1+0 records in
1+0 records out
512 bytes (512 B) copied, 16.6997 s, 0.0 kB/s

real    0m16.701s
user    0m0.000s
sys     0m0.000s
> grep Dirty /proc/meminfo
Dirty:           4199704 kB

Это мое исследование:

  • SLES11 SP4 (3.0.101-63)
  • type ext3 (rw, nosuid, nodev, noatime)
  • планировщик крайнего срока
  • более 120 ГБ восстанавливаемой памяти в то время, когда
  • dirty_ratio установлен на 40% и dirty_background_ratio 10%, срок действия 30 секунд, обратная запись 5 секунд

Вот мои вопросы:

  • 4 ГБ грязных памяти в конце теста, я делаю вывод, что планировщик ввода-вывода не был вызван в приведенном выше тесте. Это верно?
  • поскольку медлительность сохраняется после завершения первого dd, я прихожу к выводу, что эта проблема также не имеет ничего общего с выделением памяти ядром или любой «копией при записи», происходящей, когда dd заполняет свой буфер (dd всегда пишет из одного и того же буфера.)
  • есть ли способ глубже изучить, что заблокировано? Есть какие-нибудь интересные счетчики для просмотра? Есть идеи об источнике разногласий?
  • мы думаем либо об уменьшении значений dirty_ratio, либо о выполнении первого dd в синхронном режиме. Есть ли другие направления для расследования? Есть ли недостаток в том, чтобы поставить первый dd синхронно? Боюсь, что он будет иметь приоритет над другими «легальными» процессами, выполняющими асинхронную запись.

см. Также

https://www.novell.com/support/kb/doc.php?id=7010287

ограничить сброс фона Linux (грязные страницы)

https://stackoverflow.com/questions/3755765/what-posix-fadvise-args-for-sequential-file-write/3756466?sgp=2#3756466

http://yarchive.net/comp/linux/dirty_limits.html


EDIT:[1292 visible) на том же устройстве существует файловая система ext2 . На этом девайсе вообще нет зависаний! Единственное влияние на производительность возникает во время очистки грязных страниц, когда синхронный вызов может занимать до 0,3 секунды, что очень далеко от того, что мы испытываем с нашей файловой системой ext3.


EDIT2: https://www.novell.com/support/kb/doc.php?id=7016100

Фактически под SLES11 dd открывает файл с

open("zer", O_WRONLY|O_CREAT|O_DSYNC, 0666) = 3

и O_DSYNC == O_SYNC!

Заключение :

Для моего случая использования мне, вероятно, следует использовать

dd if=/dev/zero of=zer oflag=dsync bs=512 count=1 conv=notrunc

В SLES11 выполнение oflag = sync действительно будет запускаться oflag = dsync независимо от того, что говорит strace.

5
задан 23 May 2017 в 15:41
3 ответа

Пару вещей, которые меня интересуют.

  1. сначала создаем большой файл с fallocate, а затем записываем в него.

  2. Установка dirty_background_bytes намного ниже (скажем, 1Гб) и использование CFQ в качестве планировщика. Обратите внимание, что в этом тесте, возможно, было бы лучшим представлением, чтобы запустить малый в середине большого прогона.

Таким образом, для варианта 1, вы можете обнаружить, что вы избегаете всех семантик data=ordered, так как выделение блока уже сделано (и быстро), так как оно было предварительно распределено через fallocate, и метаданные устанавливаются перед записью. Было бы полезно проверить, действительно ли это так. У меня есть некоторая уверенность, хотя это улучшит производительность.

Для варианта 2 можно использовать ионику немного больше. Deadline явно быстрее, чем CFQ, хотя CFQ пытается организовать IO для каждого процесса так, чтобы вы нашли, что это дает вам лучшую долю IO через каждый процесс.

Я читал где-то (сейчас не могу найти источник), что dirty_background_ratio заблокирует запись против отдельного процесса коммитинга (фактически делая большой процесс медленнее), чтобы один процесс не проголодался, а все остальные. Учитывая то, как мало информации об этом поведении я могу найти сейчас, у меня меньше уверенности, что это сработает.

О: Я должен отметить, что fallocate полагается на extents, и вам нужно будет использовать ext4.

.
3
ответ дан 3 December 2019 в 01:30

Я отвечаю на свои вопросы, но если бы кто-нибудь мог предложить что-то лучшее, я был бы чрезвычайно признателен :)

имея 4 Гб грязной памяти в конце теста, я пришел к выводу, что планировщик ввода-вывода не был вызван в вышеуказанном тесте. Так ли это?

Это совершенно неправильно. Объем грязной памяти не является хорошим индикатором. Это можно легко доказать, просто запустив iostat и проверив, что при запуске dd oflag=sync происходит много записей.

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

perf record -e 'jbd:*' -e 'block:*' -ag

Для более новых ядер, замените jbd на jbd2.

Есть идеи об источнике разногласий?

На самом деле для ext3 с data=ordered, поток journalling отвечает за промывку данных на диске. Промывка происходит в порядке записи. Частотой промывки можно управлять с помощью опции commit при монтировании файловой системы.

Интересный эксперимент: монтируйте файловую систему с помощью commit=60 и отключите поток обратной записи. При запуске первого dd он завершается за 2 с, и iostat показывает, что IO не генерировался!

При запуске второго dd с oflag=sync, все IO, генерируемые первым dd, смываются на диск.

мы подумываем либо об уменьшении значений dirty_ratio, либо о выполнении первого dd в синхронном режиме.

для записи оба решения дают хорошие результаты. Другая хорошая идея - поместить эти большие файлы в отдельную файловую систему (возможно, смонтированную с data=writeback)

Это не связано специально с SLES11 или старыми ядрами. Такое же поведение наблюдается на всех ядрах, которые я пробовал

.
2
ответ дан 3 December 2019 в 01:30

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

Ext4, XFS, ZFS и BTRFS в этом отношении гораздо лучше. Учитывая, что ext4 более или менее подменяет ext3, вам действительно стоит обновить свою файловую систему.

.
1
ответ дан 3 December 2019 в 01:30

Теги

Похожие вопросы