Я пишу индексатор, используя python, который индексирует документы и вставляет их в базу данных. Раньше это был одиночный процесс, но теперь я перешел на многопроцессорную обработку с 4 запущенными параллельными процессами. После каждого извлечения текста он вставляется в базу данных и выполняет фиксацию.
Теперь возникает проблема ввода-вывода, основная проблема ввода-вывода - это не мой процесс, а система журналирования jdb2 EXT4. Он составляет 99,99% и заставляет ЦП ждать ввода-вывода при каждой фиксации MySQL.
Я видел, как у многих возникала эта проблема в Интернете, и их решение - смонтировать с помощью барьера = 0. Это полностью отключит ведение журнала? На моих серверах есть ИБП, и мне так хочется?
Всегда будет компромисс между отказоустойчивостью и производительностью.
С 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
Я выбрал следующую последовательность компромиссов для повышения производительности:
sync_binlog = 0
: это первая конфигурация MySQL, в которой я отказался от полной отказоустойчивости. Причина этого в том, что он дает значительное улучшение производительности, особенно там, где binlog_format=row
(к сожалению, требуется для Jira). Я использую достаточно реплик MySQL в кластере, поэтому, если бинлог будет поврежден из-за сценария потери питания, я бы сделал двоичную копию с другой реплики.innodb_flush_log_at_trx_commit = 2
: Хотя для полного соответствия ACID требуется значение 1, при значении 2 "буфер журнала записывается в файл при каждой фиксации, но операция сброса на диск не выполняется. Однако сброс на log выполняется один раз в секунду также при значении 2. Обратите внимание, что промывка раз в секунду не гарантируется на 100%, что происходит каждую секунду из-за проблем с планированием процесса ». (цитата из документации MySQL)data=writeback
. Обратите внимание, что если это ваша корневая файловая система, вам также потребуется передать параметр командной строки ядра. Я сделал несколько шагов по этому поводу на Coderwall.innodb_flush_method
. Показано, что O_DIRECT улучшает производительность в некоторых рабочих нагрузках, но не факт, что это будет работать в вашей среде.innodb_io_capacity
, и настройте такие параметры, как innodb_adaptive_flushing
, innodb_read_io_threads
, innodb_write_io_threads
, innodb_purge_threads
, и другие возможные настройки.Поместите базу данных в файловую систему без ведения журнала. По крайней мере, более крупные серверы (oracle, sql server) имеют собственную функцию журнала (журнал транзакций) и соответственно оптимизируют свой ввод-вывод. У вас есть журнал и база данных в отдельных файловых системах и на дисках, и вы полагаетесь на внутренние функции базы данных для обработки неправильного ввода-вывода. Обычно нет изменений файловой системы (более крупная установка), кроме даты записи, в любом случае, потому что файлы не расширяются - они будут сгенерированы с их «окончательным» размером (хорошо, администраторы могут это изменить), и изменения, как я сказал, отслеживаются базой данных журнал транзакций уровня.
Вы также можете сообщить нам, какой у вас уровень оборудования. Большинство людей недооценивают это IOPS является ограничивающим фактором для базы данных, и думаю, что небольшой набор дисков - подходящая среда для большой базы данных. Хотя некоторые из нас работают с базами данных, используя большее количество дисков, потенциально поддерживая большее количество операций ввода-вывода в секунду.
Это старый вопрос, но мы столкнулись с теми же проблемами (высокий уровень ожидания ввода-вывода и ужасная скорость вставки / обновления) на прошлой неделе на новом выделенном сервере, и это решение напрямую решает эту проблему.
Отключение ведения журнала с помощью 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
и это было убийство производительность.
Percona подтверждает это здесь. Мы устанавливаем его по умолчанию 0
производительность выросла более чем на 500%.
Вполне вероятно, что ваш бэкэнд ввода-вывода не очень хорошо справляется с нагрузкой. Вы должны убедиться, что ваша файловая система не ведет журнал данных. Я бы предложил использовать data=writeback,relatime,nobarrier
параметры для монтирования раздела данных вашей базы данных в качестве первой быстрой и грязной оптимизации.
Кроме того, судя по вашим симптомам, вы, по-видимому, не используете кеширование записи с вашим контроллером. Убедитесь, что вы используете кэш записи с батарейным или флеш-резервом на вашем контроллере и включите его - это должно дать вам значительный прирост производительности без значительного увеличения риска потери или повреждения данных. Обратите внимание, что использование кеша записи без аккумулятор или резервная вспышка значительно увеличивает риск потери или повреждения данных - так что делайте это только в целях тестирования и / или если вы можете понести убыток.
Какой механизм базы данных вы используете для вставки этих данных?
Если это MyISAM: он должен блокировать всю таблицу во время записи, поэтому запуск параллельных потоков вставки убьет ЛЮБУЮ систему, независимо от ее мощности.
Убедитесь, что вы используете InnoDB для этих таблиц.
Кроме того, это напрямую не связано с mysql, но у некоторых HD есть проблемы с ext4 из-за агрессивного управления питанием ... когда это происходит, нагрузка на машину увеличивается без какой-либо видимой активности.
Попробуй отключить. сначала проверьте, какое у вас значение (если вам нужно вернуть его без перезагрузки), а затем отключите его.
Проверить текущее значение:
hdparm -B /dev/sda
Отключить это
hdparm -B 255 /dev/sda
(или как там у вас HD) и протестируйте. Вероятно, не поможет для большинства проблем, но может помочь некоторым пользователям. Перезагрузка сбросит значение или вручную заменит 255 на предыдущее значение.
Если это поможет, проверьте /etc/default/hdparm
или /etc/hdparm.conf
для более постоянной конфигурации, установив ее при загрузке.