Improve hard drive write speed with write-back caching
First let’s explain what is write-back caching and how it works. Write-back caching is a feature available on most hard drive’s to allow hard drive collect all data in hard drive’s cache memory before are permanently written. Once certain amount of data is collected in hard drive’s cache memory, the whole data chunk are transferred and stored with a single event.
As a result the reduction write events can improve hard drive’s data transfer thus improve write speed. To check whether write-back caching is enable on your hard drive use:
The write-back cache is enable by default on most hard drives. This technology is especially important for SSD ( Solid Sate Drives ) which are based on flash technology which has limited number of write/erase cycles. By transferring data first to volatile cache memory and write them in single batch, the write-back caching reduces life cycle of most of the SSD’s.
Not all system’s belong to the same «turn-on write-back caching» recommendation group as write-back caching caries a risk of data loss in the event such as power failure etc. In the event of power failure, data residing in the hard drive’s cache do not get a chance to be stored and a lost. This fact is especially important for database system. In order to disable write-back caching set write-caching to 0:
Оптимизация Linux под нагрузку. Кэширование операций записи на диск.
Недавно на одном из виртуальных серверов столкнулся с проблемой долгой записи на диск. И под эту тему нашел интересную статью, в которой подробно рассмотрен вопрос функционирования кэширования операций записи на диск в Linux. Сегодня будет перевод этой статьи.
Кэширование в Linux
При записи данных на диск (любой программой) Linux кэширует эту информацию в области памяти, называемой Page Cache (страничный кэш). Информацию об этой области памяти можно посмотреть с помощью команд free, vmstat или top. Полную информацию об этой области памяти можно посмотреть в файле /proc/meminfo. Ниже приведен пример этой файла на сервере с 4-мя GB RAM:
Размер Page Cache показан в параметре «Cached», в данном примере он составляет 2,9 GB. При записи страниц в память размер параметра «Dirty» увеличивается. При начале непосредственно записи на диск будет увеличиваться параметр «Writeback» до тех пор, пока запись не закончится. Достаточно сложно увидеть параметр «Writeback» высоким, так как его значение увеличивается только во время опроса, когда операции ввода/вывода (I/O) поставлены в очередь, но еще не записаны на диск.
Linux обычно записывает данные из кэша на диск с помощью процесса pdflush. В любой момент в системе запущено от 2 до 8 потоков pdflush. В файле /proc/sys/vm/nr_pdflush_threads можно посмотреть сколько в данный момент активных потоков. Каждый раз все существующие потоки pdflush заняты по крайней мере 1 секунду. Новые потоки пытаются записать данные в свободные очереди устройств, таким образом, чтобы на каждое активное устройство был 1 поток сбрасывающий данные из кэша. Каждый раз по прошествии секунды без какой либо активности со стороны pdflush убирается 1 поток. В Linux можно настроить минимальное и максимальное количество pdflush потоков.
Настройка pdflush
Каждый поток pdflush контролируется несколькими параметрами в /proc/sys/vm:
- /proc/sys/vm/dirty_writeback_centisecs (default 500): в сотых долях секунд. Этот параметр означает как часто pdflush возобновляет работу для записи данных на диск. По умолчанию возобновляет работу 2 потока каждые 5 секунд.
Возможно недокументированное поведение, которое пресекает попытки уменьшения dirty_writeback_centisecs для более агрессивного кэширования данных процессом pdflush. Например, в ранних версиях ядра 2.6 Linux в файле mm/page-writeback.c код включал логику, которая описывалась «если запись на диск длится дольше, чем параметр dirty_writeback_centisecs, тогда нужно поставить интервал в 1 секунду». Эта логика описана только в коде ядра, и ее функционирование зависит от версии ядра Linux. Так как это не очень хорошо, поэтому вы будете защищены от уменьшения этого параметра. - /proc/sys/vm/dirty_expire_centiseconds (default 3000): в сотых долях секунд. Этот параметр указывает как долго данные могут находится в кэше, после чего должны быть записаны на диск. Значение по умолчанию очень долгое: 30 секунд. Это означает, что при нормальной работе до тех пор пока в кэш не запишется достаточно данных для вызова другого метода pdflush, Linux не будет записывать данные на диск, находящиеся в кэше менее 30 секунд.
- /proc/sys/vm/dirty_background_ratio (default 10): Максимальный процент оперативной памяти, который может быть заполнен страничным кэшем до записи данных на диск. Некоторые версии ядра Linux могут этот параметр устанавливать в 5%.
В большинстве документации этот параметр описывается как процент от общей оперативной памяти, но согласно исходным кодам ядра Linux это не так. Глядя на meminfo, параметр dirty_background_ratio расчитывается от величины MemFree + Cached — Mapped. Поэтому для нашей демонстрационной системы 10% составляет немного меньше, чем 250MB, но не 400MB.
Итого: Когда pdflush начинает запись?
В конфигурации по умолчанию, данные, записываемые на диск, находятся в памяти до тех пор пока:
- они дольше 30 секунд находятся в памяти;
- кэшированные страницы занимают более 10% рабочей памяти.
Если на сервере операции записи происходят часто, то однажды будет достигнут параметр dirty_background_ratio, и вы сможете увидеть, что вся запись на диск идет только через этот параметр не дожидаясь истечения параметра dirty_expire_centiseconds.
Процесс записи страниц
Параметр /proc/sys/vm/dirty_ratio (default 40): Максимальный процент общей оперативной памяти, который может быть выделен под страничный кэш, до того как pdflush будет писать данные на диск.
Примечание: Во время записи на диск все процессы блокируются на запись, не только тот который заполнил буфер на запись. Это может вызвать спровоцировать блокировку одним процессов всех операций вводы/вывода в системе. Провести этот
Рекомендации по оптимизации Linux для операций, требующий частой записи
Обычно люди при попытке увеличения производительности дисковой подсистемы сталкиваются с проблемой, что Linux буферизует слишком много информации сразу. Это особенно трудно для операций, требующий синхронизации файловой системы, использующих вызовы fsync. Если во время такого вызова в кэше много данных, то система может «подвиснуть» пока не закончится этот вызов.
Другая частая проблема происходит потому что слишком много требуется записать до того, как начнется запись на физический диск, операции ввода/вывода происходят чаще, чем при нормальной работе. Вы получите более долгие периоды, когда запись на диск не происходит, пока большой кэш не будет заполнен, после чего сработает один из триггеров pdflush и данные запишутся на максимальной скорости.
dirty_background_ratio: Основной инструмент настройки, обычно уменьшают этот параметр. Если ваша цель снизить количество данных, хранимое в кэше, так что данные будут писаться на диск постепенно, а не все сразу, то уменьшение этого параметра наиболее эффективный путь. Более приемлемо значение по умолчанию для систем имеющих много оперативной памяти и медленные диски.
dirty_ratio: Второй по значимости параметр для настройки. При значительном снижении этого параметра приложения, которые должны писать на диск, будут блокироваться все вместе.
dirty_expire_centisecs: Попробуйте уменьшить, но не сильно. Позволяет уменьшить время нахождения страниц в кэше до записи на диск, но это значительно снизит среднюю скорость записи на диск, т.к. это менее эффективно. Это особенно проявится на системах с медленными дисками.
Инструкция по настройке параметров
В файле /etc/sysctl.conf вносим, например:
После синхронизируем данные кэша и диска, очистим кэш и сохраним параметры.
mdadm and scsi wce bit enabled (Write Cache Enable)
Имеется сервер, в него через hba подключен ряд дисков. Никаких батареек не используется, сервер также подключен без ups. Из дисков собран программный mdadm raid массив.
Правильно понимаю, что в таком случае на всех дисках нужно повыключать встроенный writeback cache? Имеется ввиду WCE bit в SCSI caching mode page диска:
Т.е. в текущей ситуации, когда кэш диска включен, SCSI WRITE может вернуть «ok» верхнему уровню до того, как переданные данные фактически запишутся. И поэтому будет возможна ситуация после потери питания, когда по metadat’е mdadm часть данных будет считаться синхронизированной и чистой, а фактически будет не так.
Но почему в таком случае writeback cache на дисках всегда по умолчанию включен, ведь чаще не используют никакого резервного питания, чем наоборт. А когда используют, тогда и включают все возможные кэши. Или я что-то неправильно понял и mdadm использует какой-то механизм для работы в обход дискового кэша?
Но почему в таком случае writeback cache на дисках всегда по умолчанию включен
ведь чаще не используют никакого резервного питания, чем наоборт.
Почему Вы так решили? Диски у Вас в чем стоят? JBOD-корзине?
И поэтому будет возможна ситуация после потери питания, когда по metadat’е mdadm часть данных будет считаться синхронизированной и чистой, а фактически будет не так.
Если сервер у Вас без резервного питания, то такие «мелочи» Вас тем более волновать не должны — кеши файловой системы и mdadm-массива все равно пропадут при потере питания.
Смотря что иметь ввиду под резервным питанием. Конечно у сервера 2 блока питания подключенных в разные лучи в стойке, и конечно владелец ЦОД резервирует питание. Но проблемы с питанием в конкретной стойке все равно могут случиться по неподкотрольным владельцу сервера причинам.
Также у сервера может быть и один блок питания, тогда еще он сам может стать точкой отказа. Никакое резервирование питания не поможет.
В случае, если использовать аппаратный raid контроллер с батарейкой, то чтобы не случилось все данные все равно до дисков дойдут(если включить только кэш контроллера, но не дисков).
Зачем тогда вообще использовать батарейку в raid контроллере, если можно всегда полагаться на резервное питание ЦОДа?
Диски у Вас в чем стоят? JBOD-корзине?
По разному, да и без разницы. Возьмем для примера случай, когда диски локально в сервере, подключенные к системе через hba.
Если сервер у Вас без резервного питания, то такие «мелочи» Вас тем более волновать не должны — кеши файловой системы и mdadm-массива все равно пропадут при потере питания.
А вот тут поподробнее. О каком кэше mdadm идет речь? Только direct write операции: «ok» на верхний уровень только после того, как данные на диске (или в кэше диска).
Все нормальные файловые системы имеют журналирование. Данные записанные по журналу будут и на диске (если не экспериментировать с data=writeback). Потеряются только данные, которые ‘зависли’ между двумя sync’ами. Сама фс при этом не покрэшится, будет валидной и дальше продолжит работать.
А вот с кэшем диска потенциально возможна ситуация, когда fs/mdadm будут думать, что все впорядке, а данные на самом деле попортятся.
Т.е. важен не факт потери части данных — это нормально (ups не защитит от сбойной планки памяти, процессора и т.д. и последующего аварийного выключения), а важно перманентное соответствение метаданных и фактических данных.
Возможно. Но в большинстве случаев кэш включен. Ну или у меня не валидная выборка, но пока еще не попался ни одни диск с выключенным кэшем по умолчанию.
Кэш на запись на дисках по дефолту включен, потому что есть несколько механизмов сделать его безопасным: 1. ОС может отдать команду FLUSH CACHE и диск сбросит все данные из кэша на диск 2. При пропадании питания привод шпинделя переходит из режима мотора в режим генератора, а HDD, пока есть энергия от вращающихся блинов занимается двумя вещами: сбрасывает весь кэш в специальную область, предназначенную для этого и паркует головки. (по этому пункту пруфов не будет, самому захотелось прочесть подробнее о том, чем занят hdd при пропадании питания, но годных статей не нашел).
Конечно у сервера 2 блока питания подключенных в разные лучи в стойке, и конечно владелец ЦОД резервирует питание.
Зачем тогда вводить других читателей форума в заблуждение и писать про отсутствие резервного питания?
В случае, если использовать аппаратный raid контроллер с батарейкой, то чтобы не случилось все данные все равно до дисков дойдут(если включить только кэш контроллера, но не дисков).
Зачем тогда вообще использовать батарейку в raid контроллере, если можно всегда полагаться на резервное питание ЦОДа?
Потому что есть принципиальная разница между аппаратным raid-контроллером и mdadm. В первом случае программа, обсчитывающая raid-массив, крутится на процессоре контроллера в его памяти. Батарейка (сейчас скорее флеш) защищает именно эту память от сбоя по питанию. В случае mdadm все крутится в оперативной памяти сервера. И здесь роль батарейки действительно UPS выполняет. Иными словами, аппаратный raid всегда обеспечивает большую защиту, чем программный.
Разница есть — многие корзины сами резервируют питание ;).
Возьмем для примера случай, когда диски локально в сервере, подключенные к системе через hba.
Если выполняется условие, написанное вначале Вашего сообщения (ЦОД резервирует питание, сервер имеет избыточные блоки питания, подключенные к независимым линиям), то можете не отключать кеш дисков — он защищен точно также, как и кеш массива. В принципе, если ничего не зарезервировано, тоже можете не отключать — по тем же соображениям.
А вот тут поподробнее. О каком кэше mdadm идет речь?
Речь идет о так называемой проблеме raid hole. mdadm — это просто софт, реализующий алгоритмы raid. И манипуляции данными перед их записью на диски идут в RAM сервера. Соответственно, при пропадании питания эта порция данных теряется со всеми вытекающими последствиями.
Впрочем, относительно недавно эту проблему решили, введя в mdadm журналирование операций записи на массив.
Так что, если Вы используете данную фичу (доступна, начиная с ядра 4.5), то да, отключение кеша дисков имеет смысл.
Все нормальные файловые системы имеют журналирование.
Этого мало. Нужно еще, чтобы сам массив имел журналирование (см. выше).
Потому что есть принципиальная разница между аппаратным raid-контроллером и mdadm. В первом случае программа, обсчитывающая raid-массив, крутится на процессоре контроллера в его памяти. Батарейка (сейчас скорее флеш) защищает именно эту память от сбоя по питанию. В случае mdadm все крутится в оперативной памяти сервера. И здесь роль батарейки действительно UPS выполняет. Иными словами, аппаратный raid всегда обеспечивает большую защиту, чем программный.
Не правда, батарейка на рейд контроллере нужна только при использовании writeback кэша RAID контроллера, а у mdadm writeback кэша нету (его можно сделать другими инструментами), а значит все, что mdadm пишет пишется сразу на диск (или в кэш самого диска). Исчезновение питания для mdadm не страшно и не должно побить данные.
Другое дело, что в лине есть системный writeback кэш, который работает на уровне файловой системы. Именно поэтому все приложения, которые заботятся о консистентности данных, например БД, открывают файлы с опцией O_DIRECT
Не правда, батарейка на рейд контроллере нужна только при использовании writeback кэша RAID контроллера
Да, конечно, забыл это указать. Собственно говоря, именно этот режим и позволяет отключать кеш дисков без потери производительности.
а у mdadm writeback кэша нету (его можно сделать другими инструментами), а значит все, что mdadm пишет пишется сразу на диск (или в кэш самого диска).
А вот это не совсем верно. Читайте статью, ссылку на которую я приводил выше — журналирование массивов не просто так придумали.
Другое дело, что в лине есть системный writeback кэш, который работает на уровне файловой системы.
Здесь тоже журнал файловой системы позволяет избегать неконсистентности данных.
А вот это не совсем верно. Читайте статью, ссылку на которую я приводил выше — журналирование массивов не просто так придумали.
Спасибо, почитал, интересная инфа, не знал.
Зачем тогда вводить других читателей форума в заблуждение и >писать про отсутствие резервного питания?
Да, не совсем правильно выразил мысль. Изначально имелось ввиду отсутствие дополнительной резервации (например описанные вами jbod-корзины с встроенным резервным питанием), кроме той, что используется в ЦОДе.
Речь идет о так называемой проблеме raid hole.Впрочем, >относительно недавно эту проблему решили, введя в mdadm >журналирование операций записи на массив.
То, что тут описано, имеет отношение только к raid5 и производным массивам в случае аварийного выключения в момент, когда данные в пределах страйпа изменились, а xor от них не успел записаться на диск и при этом после старта сервера один из дисков, где были данные этого страйпа, вышел из строя, прочитать с него ничего нельзя. Т.е. это другой тип проблем к writeback кэшу отношения не имеющий. Даже, если случается такой тип ошибки, рейд массив и все уровни выше знают, что операция записи по определенному адресу не прошла и в большнистве случаев данные можно будет привести к валидному виду. Будет известно хоть, что восстанавливать.
Принципиальное отличие — в случае прозрачного writeback кэша на дисках, все прослойки ПО работающие с этими дисками не смогут понять после сбоя, что часть данных не валидна (если определенным алгоритмом этим кэшем не управлять и не помечать, где он сброшен, а где нет).
Для простоты предлагаю рассматривать RAID10 в контексте данного топика.
то можете не отключать кеш дисков — он защищен точно также, как и кеш массива.
Не также, речь про случай, когда writeback кэш в массиве не используется, про остальное написано выше.
Иными словами, аппаратный raid всегда обеспечивает большую защиту, чем программный.
Зависит от вендора и технологий, кооторые он использует. Журналирование, да, для частного случая безопасности добавит.
Этого мало. Нужно еще, чтобы сам массив имел журналирование (см. выше).
Имеет значение только в частном случае, описанном выше.
ОС может отдать команду FLUSH CACHE и диск сбросит все данные из кэша на диск
Вот, изначально это и интересовало. Использует ли mdadm SYNCHRONIZE CACHE по какому-либо алгоритму и помечает отдельно где-либо, что сброшено, а что нет? В документации вроде не описано и области под это дело в metadat’е не выделено (для помечания не сброшенных на диск данных SYNCHRONIZE CACH’ом).
2. При пропадании питания привод шпинделя переходит из режима мотора в режим генератора, а HDD, пока есть энергия от вращающихся блинов занимается двумя вещами: сбрасывает весь кэш в специальную область, предназначенную для этого и паркует головки
Если эта схема работает в современных дисках, то она бы все объясняла. Правда под этот случай не попадают ssd диски.
Эта схема тоже актуальна только для крутящихся дисков, в случае ssd быстрее записать сразу в нужную область, чем в распределенную кэш-область по всему диску.