Как root я вчера сделал
dd if=/dev/zero of=/var/lib/libvirt/images/dat.img bs=1G count=1000
и в течение многих часов сервер полностью не отвечал.
Контроллер рейда - HP P410 с 4 дисками в рейде 1 + 0.
Это проблема, которую я использовал bs=1G
или, может быть, CentOS нужен параметр ядра, поэтому тяжелый ввод-вывод не может остановить хост?
Вопрос
Кто-нибудь может объяснить, почему это происходит?
Пс. в следующий раз я создам разреженный файл, но сейчас я хотел бы понять, как предотвратить максимальную загрузку хоста вводом-выводом.
Короткий ответ: сервер перестает отвечать, потому что вы заполнили почти всю память грязными страницами (то есть: данные, которые должны быть удалены).
Длинный ответ: как правило, операции записи не передают данные на резервное устройство немедленно. Скорее они кэшируются в кэше страниц. Это сделано из соображений производительности: хранилище (особенно жесткие диски) довольно медленное по сравнению с ЦП / памятью, поэтому кэширование в максимально возможной степени значительно увеличивает скорость ввода-вывода. Однако, если вы вообще пишете слишком много, кэш страниц будет лихорадочно (и с высоким приоритетом) сбрасывать на диски как можно больше данных. Это заставляет вызывающий процесс перейти в "глубокий сон" - это означает, что вы не можете его прервать, потому что, ну, это не действительно работает, скорее сам ждет, когда его разбудит ядро. Более того, поскольку очистка грязных данных является дорогостоящей и высокоприоритетной операцией, весь сервер становится очень медленным.
Тем не менее, как вы можете создавать большие файлы изображений, не сокращая сервер до обхода? У вас были разные варианты:
dd
команда, добавляющая oflag=direct
вариант: это вызовет dd
к обходить кеш страницы, напрямую записывая на диски. Я также предлагаю использовать буфер меньшего размера, например: 1 МБ, используя что-то подобное dd if=/dev/zero of=/var/lib/libvirt/images/dat.img bs=1M count=1000000
. Обратите внимание, что эта команда выше воля несколько замедлить сервер во время выполнения (все-таки вы пишете на диски), но и рядом с вами первой попытки;fallocate
команда, то есть: fallocate /var/lib/libvirt/images/dat.img -l 1G
. При выделении с помощью обработки метаданных и без записи реальных данных эта команда вернется почти сразу, не вызывая замедления. Многие современные файловые системы поддерживают его, за исключением ZFS;truncate --size=1G /var/lib/libvirt/images/dat.img
. Эта команда вернется немедленно, практически не вызывая операций ввода-вывода.dd
выделяет буфер размером bs
- если это значительный кусок вашей памяти, он вытеснит другую память и вызовет подкачку.
Хуже того, bs
буфер записывается за одну операцию. Это может на время связать вашу систему хранения. В сочетании с переключением сверху это может серьезно затруднить работу системы.
Итак, разумно использовать, например, bs=16M
для вашей задачи. Это достаточно приличный размер буфера, чтобы обеспечить эффективный ввод-вывод, при этом он достаточно детализирован, чтобы ничего не связывать слишком сильно.