Затронули вчера на
интенсиве вопрос мониторинга баз данных. Говорили про MySQL, но физика процесса одинакова для всех.
Основная метрика мониторинга нагрузки БД это количество одновременно выполняемых запросов. В MySQL она называется threads_running, посмотреть ее можно выполнив команду
SHOW GLOBAL STATUS LIKE 'threads_running';
а в экспортере ее можно найти под именем mysql_global_status_threads_running
Почему эта метрика самая важная?
На железке где работает ваша база есть определенное количество ядер. Каждое ядро может в каждый конкретный момент времени может выполнять один запрос. Если количество активных запросов в моменте меньше или равно количеству ядер - база работает максимально быстро, каждый запрос получает процессорное время в тот момент когда оно нужно.
При увеличении количества активных запросов (важно не путать с количеством подключений threads_connected) в очередь на исполнение к каждому ядру CPU становится больше одного запроса, но в этот момент база продолжает эффективно обрабатывать запросы за счет того, что часть времени на обработку запроса процессор проводит в ожидании сети, диска и данных из памяти - это время используется для параллельной обработки запросов и до какого-то момента время выполнения каждого запроса растет не сильно.
Ситуация начинает резко ухудшаться с момента, когда на одно ядро приходится больше двух активных запросов. Свободного времени у ядер уже нет, поэтому параллельная обработка требует постоянного переключения потоков исполнения между запросами, что в свою очередь увеличивает время выполнения запроса.
При нагрузке х3 к количеству ядер время выполнения запроса увеличивается примерно в два раза, система нагружена, но все еще стабильна.
Стабильность быстро заканчивается при дальнейшем повышении нагрузки. Если на железку с 24 ядрами одновременно подать около сотни запросов, верхние 5% статистики улетят в космос, а пользователи получат первые пятисотки, хотя статистика пропускной способности будет показывать красивый график роста.
Дальнейшее увеличение нагрузки приводит к экспоненциальному росту времени ответа и фактической недоступности сервиса для пользователей. И это мы говорим про работу базы на предсказуемом ржавом железе. В облачной виртуалке все сильно интереснее.
Например виртуалки на яндексе, одну из которых мы вчера мучали на интенсиве, могут кратковременно выдавать больше CPU ресурсов чем то, что вы видите через lscpu. На вчерашних тестах мы наблюдали увеличение пропускной способности практически без влияния на время выполнения запросов при исполнении до десяти (!) параллельных потоков на виртуалке с двумя официально оплаченными ядрами.
Значит ли что виртуалка быстрее железки? Увы, это значит, что метрики виртуалки могут соответствовать погоде на марсе, а не вашим ожиданиям. Производительность может в любой момент просесть из-за нагрузки у "соседа", виртуалка может поменять характеристики после обычного ребута, переехав на другую железку, поэтому бенчмарки в облаке это всегда отдельный вид развлечения.
А если активные запросы висят, но используют CPU, например ожидают блокировки? Это ситуация ни чем не лучше. Заблокированные запросы, так же как и обычные медленные, блокируют исполнение кода воркерами на стороне бекенда, вызывая перегрузку бека, автоскейлинг, новые коннекты, вызывая снежный ком и приводя к глобальному отказу.
tldr; основной метрикой нагрузки на базу является количество одновременно работающих запросов. Если метрика пробивает трехкратное количество ядер - можно смело алертить и смотреть в чем причина.
Сегодня продолжим, а в следующий вторник повторим курс с начала. Поучаствовать:
https://fournines.timepad.ru/event/3984942/P.S. Накиньте огонечков, если хотите что бы сюда тоже писал всякое интересное.
@downtime_bar #MySQL #события