Бенчмарки после Meltdown/Spectre: PostgreSQL -17%, MySQL -10% на случайном чтении
Два месяца после патчей Meltdown/Spectre - публикуем цифры с реальных серверов клиентов и рекомендации по компенсации потерь на СУБД-нагрузке.
Публикация итоговых бенчмарков производительности после патчей Meltdown/Spectre на клиентских серверах ADG
Прошло около двух месяцев с момента, когда мы зафиксировали первые просадки после KPTI-патча. С тех пор накопили нормальную выборку по клиентским серверам - хватит, чтобы говорить цифрами, а не ощущениями.
Коротко: PostgreSQL на случайном чтении теряет до 17%, MySQL - около 10%. Веб- и приложенческие серверы почти не чувствуют. Всё зависит от профиля syscall'ов на единицу полезной работы.
Методология
Мы не запускали синтетику ради синтетики. Брали метрики с реальных клиентских серверов через Zabbix: IOPS, latency, CPU steal + sys time, TPS на уровне СУБД. Сравнивали скользящее среднее за неделю до патча и через две недели после стабилизации. Серверы - преимущественно bare metal с Intel Xeon Broadwell и Skylake, Ubuntu 16.04/Debian 9, PostgreSQL 9.6 и MySQL 5.7.
Это не лабораторный тест - это что было в production. У кого-то нагрузка ровная, у кого-то с суточным профилем. Разброс есть, но паттерн читается чётко.
Что получили по PostgreSQL
OLTP с короткими транзакциями ударился сильнее всего. На серверах с высокой частотой SELECT'ов по первичному ключу и случайным чтением из буферного кеша просадка достигла 17%. Механика понятна: короткая транзакция - это почти один syscall на запрос. Умножь на тысячи TPS - и overhead от сброса TLB при каждом переходе в kernel становится ощутимым.
- Случайное чтение (OLTP, pgbench TPC-B) - просадка 12-17% в зависимости от сервера.
- Последовательное сканирование - 3-5%, в пределах погрешности на части серверов.
- INSERT-intensive нагрузка с
synchronous_commit = on- 8-12%. fsync-вызовы дорожают. - Аналитические запросы (длинные SELECT, агрегация) - 2-4%. Запрос живёт в userspace большую часть времени.
На серверах с Skylake и включённой PCID-оптимизацией цифры чуть лучше - разница примерно в треть от общей просадки. На Broadwell без revised микрокода (его мы так и ждём) - по верхней границе диапазона.
MySQL
MySQL 5.7 на InnoDB показал около 10% на случайном чтении в режиме read-heavy нагрузки. На write-heavy - немного хуже. В целом MySQL при аналогичном профиле нагрузки страдает чуть меньше PostgreSQL - вероятно, разница в том, как реализован буферный пул и внутренняя блокировочная механика. Это наблюдение, не вывод - нужно больше данных.
Что не пострадало
Веб-серверы (nginx) - просадка в пределах 1-2%, на фоне сетевого jitter'а неразличима. Приложенческие серверы на Java/Python без интенсивного IO - аналогично. Cron-задачи, скрипты - не заметили ничего.
Вывод банальный: если ваша нагрузка - это много коротких системных вызовов, вы чувствуете патч. Если нагрузка «толстая» по userspace - не чувствуете.
Рекомендации по компенсации
Полностью убрать overhead нельзя - это цена, которую мы платим за изоляцию. Но снизить реально.
Connection pooling перед PostgreSQL. Если PgBouncer не стоит - поставьте. Снижает количество активных соединений и, соответственно, частоту syscall'ов на уровне принятия соединений. На серверах, где мы его добавили в рамках аудита, просадка компенсировалась на 3-5 процентных пунктов.
Пересмотр частоты коммитов. Приложения, которые делают COMMIT на каждую операцию, нарвались больнее всего. Группировка транзакций там, где логика позволяет, снижает fsync-давление.
PCID на новых ядрах. Проверьте, что ядро использует PCID-оптимизацию: dmesg | grep -i pcid. Ядра 4.14+ на процессорах с флагом pcid в /proc/cpuinfo делают частичный сброс TLB вместо полного - это экономит часть overhead. Если сервер стоит на 4.4 (Ubuntu 16.04 по умолчанию) - апгрейд ядра до HWE-стека (4.13+) даёт ощутимый эффект.
Кеш на уровне приложения. Избито, но факт: запрос, который не ушёл в БД, не заплатил ни за что. На нагрузках с высоким hit rate Redis или Memcached перед базой заметно компенсируют потери.
Профилировать свою нагрузку, а не чужую. Наши цифры - это наша выборка. На вашем сервере с вашей нагрузкой может быть 5%, а может быть 20%. Прогоните pgbench или sysbench против своей схемы - получите честную картину.
Что дальше
По Meltdown - ядерный патч закрыт, тема технически решена, живём с overhead. По Spectre Variant 2 - ждём нормального revised микрокода от Intel для Broadwell/Haswell. Пока его нет, retpoline в ядре закрывает часть векторов, но не полностью.
Если ваш сервер с PostgreSQL после января начал немного хрипеть - теперь знаете почему. Помочь оценить реальную просадку и найти точки компенсации можно в рамках аудита инфраструктуры: берём метрики до/после, сравниваем, даём конкретные рекомендации по конфигурации - не общие слова.