У меня есть пара серверов в промышленных условиях (сеть с воздушным зазором), которые выполняют довольно легкий сбор данных телеметрии. Мы генерируем около 10 ГБ истории телеметрии за ~ 30 дней.
Вся телеметрия представлена набором таблиц, разделенных на два типа: текущее состояние и история. Таблицы состояний обычно содержат 16 строк или меньше. Таблицы истории могут быть довольно большими, но общий размер составляет около 11 ГБ. Телеметрия поступает со скоростью чуть менее 100 выборок в секунду, а таблицы истории обновляются только в том случае, если что-то меняется или прошло 30 секунд. По моим предварительным проверкам, обновление истории пропускается примерно 9 раз из 10. Таким образом, в большинстве случаев каждая выборка приводит к единственному REPLACE INTO в одной из примерно шести таблиц.
Все это работает на стандартном сервере Ubuntu 14.04 (64-разрядная версия), нагрузка на серверы Supermicro 1U с процессорами Xeon с 2015 года или около того. Меня нет на заводе, поэтому я не могу проверить точную модель.
Каждый сервер имеет 32 ГБ ОЗУ ECC.
Диски имеют конфигурацию RAID 1 с 4 дисками (заводские специалисты не действуют быстро, когда диск выходит из строя, поэтому нам нужно много резервного копирования). Все диски постоянно контролируются с помощью smartctl, и когда один из них показывает сбой или предупреждение, мы заменяем его. В декабре мы заменили диски на одном из серверов и сделали то же самое с другим.
На обоих серверах производительность MySQL обычно хорошая, время отклика на обновления таблиц состояния составляет однозначное число миллисекунд. Однако мы получаем очень резко отклоняющиеся значения. Время от времени, несколько раз в день и обычно чаще, чем один раз в час, мы видим, что один REPLACE INTO в 16-строчной таблице состояния занимает> 1,5 секунды. Это вызывает тревогу, что мы потеряли телеметрию, так что это более чем раздражает.
Все таблицы InnoDB, по одному файлу на таблицу. Discard включен для файловой системы (ext4). Я попытался изменить параметры MySQL, чтобы отключить синхронизацию при фиксации (вместо периодической синхронизации), и это, похоже, не имело никакого эффекта. У меня для InnoDB настроен журнал размером 1 ГБ, а сами файлы базы данных значительно меньше ОЗУ.
ОЗУ - это в основном (~ 60%) кэшированные данные.
Я попытался изменить типы таблиц в таблицах состояния на MyISAM, но проблема не изменилась.
Я изменил регистратор данных так, чтобы каждая таблица обрабатывалась одним потоком, и потоки пакетно помещали обновления в очередь в коммиты. Очень редко в коммите происходит более одного изменения, кроме как после одной из этих огромных задержек.
Тот факт, что MyISAM ничего не изменил (и я имею в виду, что вообще не было заметного изменения в поведении), заставляет меня подозревать RAID.
Диски новенькие (менее двух недель) Crucial MX500, 1 ТБ. Да, это потребительские диски, но скорость записи довольно низкая. И мы постоянно поддерживаем заполнение файловой системы менее чем на 40%.
Я не понимаю, что попробовать дальше. Это проблема с RAID? Это проблема конфигурации MySQL?
Я вижу задержку во всех таблицах состояний, даже в таблицах с одной строкой. В некоторых случаях строки немного велики (в одной 125 столбцов), но они все равно очень и очень маленькие.
Таблицы состояния / состояния действительно имеют первичные ключи для обеспечения уникальности данных.
У кого-нибудь есть советы, где я могу посмотреть дальше? Опять же, это промышленная установка в сети с воздушным зазором, поэтому загрузка большого количества инструментов по одному чрезвычайно болезненна, а все входящее и выходящее программное обеспечение строго контролируется.
У меня не хватило ума установить iostat на серверах, когда они были впервые установлены. Однако первоначальные тесты с hdparm -tT, казалось, показали, что на нижележащих дисках все в порядке. Никакие диски не показывают проблем в smartctl.
Замена дисков производилась по одной, так что RAID фактически является старым RAID (который был основан на MX200). При замене дисков RAID не создавался заново.
Есть ссылки на известную проблему с этой версией MySQL (что-то вроде 5.5) и REPLACE INTO, но ничто из того, что я прочитал, не говорит о том, что я должен увидеть такое большое изменение производительности.
Любые идеи были бы хорошы!
Остановка во время записи (что вы, кажется, делаете в основном) может указывать на то, что innodb_log_file_size
заполнен и ожидает очистки. Размер по умолчанию для них в 5.5 ужасно мал. Увеличение размера до 512 МБ и экземпляров до 4 было бы хорошим началом. Следуйте приведенной ниже ссылке. Следите за разницей отметок времени на них во время загрузки данных (верхний уровень каталога данных). Если они все примерно в одну и ту же минуту, они недостаточно велики. Также посмотрите на SHOW ENGINES INNODB STATUS
вывод.
ссылка: изменение размера журнала повторного выполнения вручную Хотя я бы переместил старые файлы в сторону, а не удалял их, чтобы вы могли при необходимости переместить их обратно. Резервные копии сохраняют рабочие места.
В innodb_buffer_pool_size
также должен быть установлен такой размер, чтобы удерживать активный рабочий набор (70% доступного плунжера - хорошее начало, а затем посмотрите на SHOW GLOBAL STATUS
чтобы увидеть, сколько используется).
Убедитесь, что журнал медленных запросов включен с соответствующим порогом, что поможет обнаруживать другие медленные запросы.