Назад | Перейти на главную страницу

Кэш файловой системы Linux: переместить данные из грязных в обратную запись

Мой программный RAID может записывать устойчиво 800 МБ / с. Я вижу это, когда cat /proc/meminfo |grep Writeback: возвращает> 2 ГБ. Однако в большинстве случаев обратная запись составляет около 0,5 ГБ, что дает производительность около 200 МБ / с.

Есть много данных, которые нужно записать. cat /proc/meminfo |grep Dirty: говорит, что грязный кеш составляет 90 ГБ.

Насколько я понимаю, Dirty - это то, что нужно записать, а Writeback - это то, что активно записывается на диск. Таким образом, в Dirty могут быть блоки, которые расположены на диске рядом с блоками в Writeback, и они не будут записаны одновременно.

Это может объяснить, почему у меня намного хуже производительность, если обратная запись мала, поскольку время, потраченное на поиск, намного больше, чем время, потраченное на запись нескольких дополнительных МБ.

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

-- Редактировать --

Это при низкой производительности:

$ cat /proc/meminfo
MemTotal:       264656352 kB
MemFree:          897080 kB
Buffers:              72 kB
Cached:         233751012 kB
SwapCached:            0 kB
Active:          3825364 kB
Inactive:       230327200 kB
Active(anon):     358120 kB
Inactive(anon):    47536 kB
Active(file):    3467244 kB
Inactive(file): 230279664 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:      204799996 kB
SwapFree:       204799996 kB
Dirty:          109921912 kB
Writeback:        391452 kB
AnonPages:        404748 kB
Mapped:            12428 kB
Shmem:               956 kB
Slab:           21974168 kB
SReclaimable:   21206844 kB
SUnreclaim:       767324 kB
KernelStack:        5248 kB
PageTables:         7152 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    337128172 kB
Committed_AS:     555272 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      544436 kB
VmallocChunk:   34124336300 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      149988 kB
DirectMap2M:    17649664 kB
DirectMap1G:    250609664 kB


cat /proc/sys/vm/dirty_background_ratio
1

Понижение dirty_writeback_centisecs разбивает Dirty только на еще меньшие биты.

Вы не предоставили весь вывод / proc / meminfo, поэтому я не знаю, выполняли ли вы какие-либо настройки заранее.

Вот два параметра, которые можно использовать для немедленной настройки.

/proc/sys/vm/dirty_background_ratio

 dirty_background_ratio

Contains, as a percentage of total system memory, the number of pages at which
the pdflush background writeback daemon will start writing out dirty data.

По умолчанию 10. Увеличьте его до 30 или 40 и проверьте.

/proc/sys/vm/dirty_writeback_centisecs

dirty_writeback_centisecs

The pdflush writeback daemons will periodically wake up and write `old' data
out to disk.  This tunable expresses the interval between those wakeups, in
100'ths of a second.

Setting this to zero disables periodic writeback altogether.

По умолчанию 500. Установите 300 и проверьте.

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

Я просто вычислил эти значения на основе предоставленного вами описания и предположил, что это правильно.

Если у вас установлен пакет kernel-doc, перейдите в sysctl, а затем откройте vm.txt, чтобы прочитать о нем.

Настоящая проблема заключается в том, что алгоритм очистки грязной страницы ядра Linux не масштабируется до больших размеров памяти, поэтому каждый раз, когда грязная страница в / proc / meminfo превышает 1 ГБ, скорость обратной записи постепенно снижается, и в конечном итоге / proc / sys / vm / dirty_ratio или предел / proc / sys / vm / dirty_bytes превышен, и ядро ​​начинает регулировать все операции записи, чтобы не допустить дальнейшего роста грязных страниц.

Чтобы поддерживать высокую скорость записи (в случае OP до 800 МБ / с, может легко быть 2 ГБ / с для аппаратного RAID-контроллера с кешем), вам нужно интуитивно противодействовать уменьшению / proc / sys / vm / dirty_bytes и dirty_background_bytes до 256 МБ и 64M соответственно

Обязательно сначала выполните синхронизацию, иначе система будет зависать при записи на несколько часов, пока значение грязной страницы в / proc / meminfo не упадет ниже нового значения в / proc / sys / vm / dirty_bytes. Синхронизация также займет несколько часов, но, по крайней мере, система не будет зависать в это время.

Writeback представляет размер очереди ввода-вывода.

Максимальный размер очереди ввода-вывода можно увеличить, увеличив nr_requests (и потенциально max_sectors_kb). Учитывая количество Dirty у вас есть память, я подозреваю, что вы достигли этого предела.

https://www.google.com/search?q=linux+block+queue+nr_requests+OR+max_sectors_kb

В последних ядрах вам также следует остерегаться эффекта wbt_lat_usec. Вы можете отключить это, написав 0 к нему и сбросьте его до значения по умолчанию, написав -1.

Есть еще вопрос о планировщике ввода-вывода. Многие серверы советуют использовать deadline планировщик, а не CFQ. CFQ (и, в некоторой степени, BFQ) намеренно "бездействует" диск, пытаясь запросить непрерывный последовательный ввод-вывод от одного процесса за раз.

Я не знаю, как настроить md Устройство RAID v.s. отдельные дисковые устройства, извините.

(Вы также можете попробовать измерить количество запросов ввода-вывода в очереди. atopsar -d 1, или sar -d 1, или iostat -dx 1. Однако статистика «среднего размера очереди» получено из использования ("io_ticks"), а это сообщается неверно с версии ядра 5.0. Мгновенный размер очереди остается точным. Однако существующие инструменты, как правило, показывают только средний размер очереди, потому что это было более полезное значение).