IO Wait вызывает сильное замедление (EXT4 JDB2 при 99% IO) во время Mysql Commit

14

Я пишу индексатор, использующий python, который индексирует документы и вставляет их в базу данных. Раньше это был отдельный процесс, но теперь я перешел на многопроцессорную работу с 4 параллельными процессами. После каждого извлечения текста он вставляется в базу данных и выполняет коммит.

Теперь это проблема IO, главная проблема IO - это не мой процесс, а jdb2 EXT4, система журналирования. Это на 99,99% и побуждает ЦП ожидать ввода-вывода при каждой фиксации MySQL.

Я видел многих, имеющих эту проблему в Интернете, и их решение состоит в том, чтобы установить, используя барьер = 0. Будет ли это полностью отключить ведение журнала? Мои серверы имеют ИБП и заманчиво сделать это, не так ли?

Phyo Arkar Lwin
источник
Все ваши данные InnoDB ???
RolandoMySQLDBA

Ответы:

4

Поместите базу данных в файловую систему без журналирования. По крайней мере, более крупные серверы (oracle, sql server) имеют свои собственные функции журнала (журнал транзакций) и соответственно оптимизируют свои операции ввода-вывода. У вас есть журнал и база данных на отдельных файловых системах и дисках, и вы используете внутреннюю функциональность базы данных для обработки некорректного ввода-вывода. Как правило, никаких изменений в файловой системе (более крупных) не происходит, за исключением даты записи, поскольку файлы не расширяются - они будут генерироваться с их «окончательным» размером (хорошо, администраторы могут это изменить), а изменения, как я уже сказал, отслеживаются базой данных. Уровень транзакций журнала.

Вы также можете сообщить нам, какой у вас аппаратный уровень. Большинство людей недооценивают, что IOPS является ограничивающим фактором для базы данных, и считают, что небольшой набор дисков является подходящей средой для большой базы данных. Хотя некоторые из нас работают с базами данных, используя большее количество дисков, таким образом, потенциально поддерживая большее количество операций ввода-вывода в секунду.

TomTom
источник
Я бы изменил это, чтобы использовать файловую систему, не используя журнал для данных, а только метаданные. Ext4 также может быть настроен таким образом.
the-wabbit
Да. В конце jouirnal удваивает IO - и журнал базы данных снова делает то же самое, так что вы получаете гораздо больше IOPS, чем нужно. И избыточность, которая в принципе не нужна. Система jouirnalling - это НЕОБХОДИМО, чтобы защитить файл .... но бесполезно, когда приложение уже делает это, какие базы данных делают.
TomTom
Что обеспечивает лучшую производительность при отсутствии журналирования? Благодарность!
Phyo Arkar Lwin
4

Всегда будет компромисс между отказоустойчивостью и производительностью.

При использовании MySQL на ext4 значение по умолчанию «барьеры = 1» действительно приводит к замедлению, однако первым действием не должно быть отключение ведения журнала или включение data = writeback.

Во-первых, если устойчивость очень важна, RAID с резервным питанием от батареи, безусловно, того стоит.

Варианты монтирования, которые я выбрал, особенно для RAID без аккумулятора:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Это намеренно не использует data = writeback, потому что я не хочу рисковать повреждением файловой системы, в результате чего «старые данные появляются в файлах после сбоя и восстановления журнала» (цитата из man mount ).

Идеальная конфигурация в my.cnf для полной устойчивости вокруг настроек, связанных с вводом / выводом:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

Я выбрал следующую последовательность компромиссов для повышения производительности:

  1. sync_binlog = 0Это первый конфиг MySQL, который я изменил от полной отказоустойчивости. Причина этого заключается в том, что это дает значительное улучшение производительности, особенно там, гдеbinlog_format=row (к сожалению, требуется для Jira). Я использую достаточное количество реплик MySQL в кластере, чтобы в случае повреждения бинлога из-за сбоя питания я сделал бы двоичную копию из другой реплики.
  2. innodb_flush_log_at_trx_commit = 2: Хотя для полного соответствия ACID требуется значение 1, со значением 2 "буфер журнала записывается в файл при каждой фиксации, но на нем не выполняется операция очистки на диск. Однако очистка на Файл журнала выполняется один раз в секунду, а также при значении 2. Обратите внимание, что сбрасывание один раз в секунду не гарантируется на 100% каждую секунду из-за проблем с планированием процесса ». (цитата из документации по MySQL)
  3. Обновите параметры монтирования для использования data=writeback. Обратите внимание, что если это ваша корневая файловая система, вам также нужно будет указать параметр командной строки ядра. Я собрал несколько шагов по этому вопросу в coderwall .
  4. Проверьте различные значения innodb_flush_method . Показано, что O_DIRECT улучшает производительность в некоторых рабочих нагрузках, но не считается, что это будет работать в вашей среде.
  5. Обновление до SSD - накопителей, в этом случае вы также хотите увеличить innodb_io_capacity, а также настраивать параметры , такие как innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, и другие возможные настройки.
JinnKo
источник
3

Вполне вероятно, что ваш бэкэнд ввода-вывода не справляется с нагрузкой. Вы должны убедиться, что ваша файловая система не регистрирует данные. Я бы предложил использоватьdata=writeback,relatime,nobarrier параметры для монтирования раздела данных вашей базы данных в качестве первой быстрой и грязной оптимизации.

Кроме того, исходя из ваших симптомов, вы, очевидно, не используете кеширование записи с вашим контроллером. Вы должны убедиться, что используете на контроллере кэш-память с батарейным или флэш-накопителем и включите его - это должно значительно повысить производительность без значительного увеличения риска потери или повреждения данных. Обратите внимание, что использование кэша записи без батареи или флэш-резервирования значительно увеличивает риск потери или повреждения данных - поэтому делайте это только в целях тестирования и / или если вы можете принять потерю.

заместитель Wabbit
источник
так как насчет: data = writeback, relaytime, nobarrier, а затем полностью отключить ведение журнала mysql? Я думаю, это сильно ускорит процесс?
Phyo Arkar Lwin
hdpram -i показывает, что я использую кэширование записи. так хм ??
Phyo Arkar Lwin
@ V3ss0n, вы не можете отключить ведение журнала для транзакционного движка - это его самое сердце. Вы можете переместить журнал транзакций на другой набор дисков, так как он имеет совершенно другой шаблон доступа (в основном линейные записи), чем данные вашей основной базы данных (произвольное чтение / запись) - это часто рекомендуемая конфигурация. Что касается настроек хранилища: вы используете не контроллер RAID, а просто отдельные диски с включенным кэшем записи? Это не поможет ни одной из ваших синхронных записей, поскольку они приходят с явными запросами очистки кэша.
The Wabbit
Это так nobarrierже, как barrier=0?
Ник Коттрелл
@NicCottrell да, они одинаковы.
Kouton
3

Это старый вопрос, но мы столкнулись с теми же проблемами (высокая скорость ввода-вывода и ужасная скорость вставки / обновления) на прошлой неделе на новом выделенном сервере, и это решение напрямую решает эту проблему.

Отключение ведения журнала с помощью tune2fs -O "^has_journal" /dev/<drive>было самым быстрым решением, поскольку оно устраняет ожидание ввода-вывода из-за процесса JDB2. Но это не рекомендуется, если у вас нет накопителя с батарейным питанием, потому что вы потеряете данные в случае сбоя. Таблицы InnoDB безопасны, если вы doublewriteвключили в MySQL. Но такие файлы, как .frm, журналы и т. Д. Небезопасны. Мы попытались переместить эти файлы на другой диск (особенно в журналы bin), но ожидание ввода-вывода jdb2 все еще продолжалось. Так что это не оставляло нас очень комфортно.

data=writeback,relatime,nobarrierэто не помогло ускорить процесс записи / чтения, так как отключило ведение журнала для всего раздела. Дополнительные параметры для ext4 находятся в документе EXT4 .

Настоящий виновник в нашем случае был sync_binlog. Мы установили, как 1в, /etc/mysql/my.cnfи это было убийственное представление.

Перкона подтверждает это здесь . Мы установили для него значение по умолчанию 0и производительность выросла более чем на 500%.

kouton
источник
0

Какой движок базы данных вы используете для вставки этих данных?

Если это MyISAM: он должен блокировать всю таблицу во время записи, поэтому выполнение параллельных потоков вставки уничтожит ЛЮБУЮ систему, независимо от ее мощности.

Убедитесь, что вы используете InnoDB для этих таблиц.

adaptr
источник
Так как он совершает транзакции, механизм не будет MyISAM, так как MyISAM не поддерживает транзакции.
the-wabbit
Arr, Brainfart.
Адаптер
Я использую innodb, по умолчанию mysql5.5 - innodb.
Phyo Arkar Lwin
0

Кроме того, не имеет прямого отношения к mysql, но некоторые HD имеют проблемы с ext4 из-за агрессивного управления питанием ... когда это происходит, загрузка машины увеличивается без какой-либо видимой активности.

Попробуйте отключить это. сначала проверьте, какое у вас значение (если вам нужно вернуть его без перезагрузки), а затем отключите его.

Проверьте текущее значение:

    hdparm -B /dev/sda

Отключить это

   hdparm -B 255 /dev/sda

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

Если это помогает, проверьте /etc/default/hdparmили /etc/hdparm.confдля более постоянной конфигурации, установив его при загрузке.

Игиты
источник