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

Непонимание кеша страниц и dirty_background_bytes

Я уже некоторое время смотрю на это, и все не совпадает с моими ожиданиями, но я не знаю, потому что что-то не так, или мои ожидания неверны.

Итак, у меня есть система с более чем 100 ГБ ОЗУ, и я установил свой dirty_background_bytes на 9663676416 (9 ГБ) и dirty_bytes в 2 раза больше (19327352832 или 18 ГБ)

На мой взгляд, это должно позволить мне записать до 9 ГБ в файл, но на самом деле он просто находится в памяти и не должен попадать на диск. Мой dirty_expire_centisecs по умолчанию 3000 (30 секунд).

Итак, когда я бегу:

# dd if=/dev/zero of=/data/disk_test bs=1M count=2000

и побежал:

# while sleep 5; do egrep 'Dirty|Writeback' /proc/meminfo | awk '{print $2;}' | xargs; done

(Печать грязных байтов в килобайтах, обратная запись в килобайтах и ​​WritebackTmp в килобайтах на моментальных снимках 5 секунд)

Я ожидал увидеть, как он выгружает 2 ГБ в кеш страницы, сидит там 30 секунд, а затем начинает записывать данные на диск (поскольку он никогда не превышал фоновое соотношение 9 ГБ)

Вместо этого я увидел:

3716 0 0
4948 0 0
3536 0 0
1801912 18492 0
558664 31860 0
7244 0 0
8404 0 0

Где, как только кеш страницы перескочил, он уже записывал данные, пока мы не вернулись туда, где начали.

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

Итак, я неправильно понимаю, как эти функции должны работать, или происходит что-то странное?

Это может быть побочным эффектом вашего dd отключение команды и создание нового disk_test на каждой итерации.

Попробуйте сначала создать целевой файл с одним dd if=/dev/zero of=/data/disk_test bs=1M count=2000 команду, затем запустите цикл с помощью dd if=/dev/zero of=/data/disk_test bs=1M count=2000 conv=notrunc,nocreat команда.

Пояснение: notrunc имеет значение, потому что в прошлом была добавлена ​​некоторая эвристика, чтобы предотвратить приложения, выполняющие замену через переименование и замену через усечение и сбой сразу после этого, чтобы повредить свои данные. Эта эвристика в основном принудительно сбрасывает данные, принадлежащие открытым-> записанным-> усеченным файлам.

Из смонтировать страницу руководства:

auto_da_alloc | noauto_da_alloc

Многие неработающие приложения не используют fsync (), когда noauto_da_alloc заменяет существующие файлы с помощью таких шаблонов, как

fd = open ("foo.new") / write (fd, ..) / close (fd) / rename ("foo.new", "foo")

или еще хуже

fd = open ("foo", O_TRUNC) / write (fd, ..) / close (fd).

Если auto_da_alloc включен, ext4 обнаружит шаблоны replace-via-rename и replace-via-truncate и принудительно распределяет любые отложенные блоки распределения таким образом, чтобы при следующей фиксации журнала в режиме data = order по умолчанию блоки данных новый файл будет записан на диск перед выполнением операции rename (). Это обеспечивает примерно тот же уровень гарантий, что и ext3, и позволяет избежать проблемы «нулевой длины», которая может возникнуть при сбое системы до того, как блоки отложенного распределения будут перенесены на диск.

Дайте также добычу в XFS FAQ