Борьба за отладку высокой загрузки ЦП на экземпляре Amazon RDS MySQL

21

Мы работаем с сервером MySQL RDS m1.xlarge и имеем некоторые проблемы с высокой загрузкой процессора. У нас были некоторые проблемы пару недель назад, когда загрузка процессора достигала 100% в большом случае. Когда мы увеличили размер до xlarge, это на некоторое время стабилизировало ситуацию, но загрузка ЦП постепенно увеличилась.

В течение последней недели или около того загрузка ЦП достигла максимума 90-х годов, достигнув 100% или около того вчера, что привело к остановке нашей производственной площадки. После перезагрузки сервера БД загрузка ЦП в течение нескольких часов снова поднялась до того же уровня.

Я запустил show processlist на сервере MySQL и отслеживал то же самое через администратора MySQL. Кажется, что нет никаких особо длительных запросов или большого количества запросов. Есть пара процессов, которые долгое время находятся в спящем состоянии ... это изолированные работающие демоны, работающие вне нашего основного приложения, которые взаимодействуют с базой данных. Я скопировал в вывод списка процессов ниже имена серверов, которые были изменены, чтобы дать описание того, что они из себя представляют:

+------+----------+---------------------------------------------------+--------------+---------+-------+--------------+----------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+----------+---------------------------------------------------+--------------+---------+-------+--------------+----------------------------------------------------------------------------------------+
| 13 | rdsadmin | localhost:43513 | mysql | Sleep | 14 | | NULL |
| 15 | proddbuser | app-server-1.eu-west-1.compute.internal:36460 | proddb | Sleep | 46 | | NULL |
| 451 | proddbuser | app-server-1.eu-west-1.compute.internal:55512 | proddb | Sleep | 29 | | NULL |
| 912 | proddbuser | app-server-1.eu-west-1.compute.internal:45171 | proddb | Sleep | 13 | | NULL |
| 941 | proddbuser | app-server-1.eu-west-1.compute.internal:47353 | proddb | Sleep | 53 | | NULL |
| 951 | proddbuser | app-server-1.eu-west-1.compute.internal:48014 | proddb | Sleep | 37 | | NULL |
| 1009 | proddbuser | app-server-1.eu-west-1.compute.internal:51787 | proddb | Sleep | 36 | | NULL |
| 1041 | proddbuser | app-server-1.eu-west-1.compute.internal:53777 | proddb | Sleep | 14 | | NULL |
| 1572 | proddbuser | app-server-1.eu-west-1.compute.internal:42989 | proddb | Sleep | 3 | | NULL |
| 1592 | proddbuser | app-server-1.eu-west-1.compute.internal:43279 | proddb | Sleep | 162 | | NULL |
| 2909 | proddbuser | app-server-1.eu-west-1.compute.internal:37768 | proddb | Sleep | 35 | | NULL |
| 3028 | proddbuser | app-server-1.eu-west-1.compute.internal:42568 | proddb | Sleep | 5 | | NULL |
| 3119 | proddbuser | app-server-1.eu-west-1.compute.internal:46913 | proddb | Sleep | 76 | | NULL |
| 3189 | proddbuser | app-server-1.eu-west-1.compute.internal:51466 | proddb | Sleep | 5 | | NULL |
| 3216 | proddbuser | app-server-2.eu-west-1.compute.internal:44097 | proddb | Sleep | 14552 | | NULL |
| 3218 | proddbuser | app-server-2.eu-west-1.compute.internal:44099 | proddb | Sleep | 14552 | | NULL |
| 3219 | proddbuser | app-server-2.eu-west-1.compute.internal:44107 | proddb | Sleep | 44 | | NULL |
| 3220 | proddbuser | app-server-2.eu-west-1.compute.internal:44113 | proddb | Sleep | 26 | | NULL |
| 3223 | proddbuser | app-server-2.eu-west-1.compute.internal:44184 | proddb | Sleep | 50 | | NULL |
| 3224 | proddbuser | app-server-2.eu-west-1.compute.internal:44187 | proddb | Sleep | 1 | | NULL |
| 3226 | proddbuser | app-server-2.eu-west-1.compute.internal:44208 | proddb | Sleep | 33 | | NULL |
| 3229 | proddbuser | app-server-2.eu-west-1.compute.internal:44250 | proddb | Sleep | 14 | | NULL |
| 3232 | proddbuser | app-server-2.eu-west-1.compute.internal:44279 | proddb | Sleep | 26 | | NULL |
| 3233 | proddbuser | app-server-2.eu-west-1.compute.internal:44297 | proddb | Sleep | 31 | | NULL |
| 3237 | proddbuser | app-server-2.eu-west-1.compute.internal:44334 | proddb | Sleep | 27 | | NULL |
| 3239 | proddbuser | app-server-2.eu-west-1.compute.internal:44338 | proddb | Sleep | 11 | | NULL |
| 3241 | proddbuser | app-server-2.eu-west-1.compute.internal:44356 | proddb | Sleep | 26 | | NULL |
| 3260 | proddbuser | app-server-2.eu-west-1.compute.internal:44619 | proddb | Sleep | 8 | | NULL |
| 3337 | proddbuser | utility-server-1.eu-west-1.compute.internal:45193 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 309416 LIMIT 1 |
| 3419 | proddbuser | utility-server-1.eu-west-1.compute.internal:46136 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 284530 LIMIT 1 |
| 3463 | proddbuser | app-server-1.eu-west-1.compute.internal:59619 | proddb | Sleep | 9406 | | NULL |
| 3504 | proddbuser | utility-server-1.eu-west-1.compute.internal:47063 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 260571 LIMIT 1 |
| 3577 | proddbuser | app-server-1.eu-west-1.compute.internal:34394 | proddb | Sleep | 6734 | | NULL |
| 3585 | proddbuser | utility-server-1.eu-west-1.compute.internal:47990 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 231273 LIMIT 1 |
| 3664 | proddbuser | utility-server-1.eu-west-1.compute.internal:48909 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 201525 LIMIT 1 |
| 3716 | proddbuser | app-server-2.eu-west-1.compute.internal:56301 | proddb | Sleep | 27 | | NULL |
| 3748 | proddbuser | utility-server-1.eu-west-1.compute.internal:49850 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 167839 LIMIT 1 |
| 3771 | proddbuser | my-pc:30101 | NULL | Query | 0 | NULL | show processlist |
| 3831 | proddbuser | utility-server-1.eu-west-1.compute.internal:50785 | proddb | Query | 0 | Sending data | SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 123228 LIMIT 1 |
+------+----------+---------------------------------------------------+--------------+---------+-------+--------------+----------------------------------------------------------------------------------------+

Я также должен сказать, что трафик на сайте очень низкий в этот период по сравнению с обычными часами пик, около 10% нагрузки, которую мы видим в часы пик.

У нас также есть новый мониторинг реликтов, который показывает нам, какие вызовы базы данных приложений занимают больше всего времени. Это показывает нам, что один конкретный вызов, на который приходится 99% времени, которое наше приложение тратит в БД, - это простой запрос по идентификатору, подобный следующему:

SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`id` = 123 LIMIT 1

(не совсем так же, как запросы, которые выполнялись в приведенном выше списке процессов)

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

В этой таблице около 80 000 строк, поэтому она невелика. Ожидается, что большая часть времени приложений в базе данных тратится на поиск записей в этой таблице, основная функциональность приложения основана на этом. Я сам несколько раз выполнял аналогичный запрос с моего сервера приложений к производственной базе данных, при этом загрузка ЦП остается на уровне 100%, и он отвечает в течение 1 или 2 мс.

Исходя из всего вышесказанного, мы не уверены, как продолжить нашу отладку. Интересно, есть ли у кого-нибудь идеи, какие вещи могут быть первопричиной и как их расследовать? Доступ к базовому серверу, на котором работает наш db-сервер, ограничен, так как это экземпляр Amazon RDS.

WillJThomas
источник
только что перезапустил RDS решил мою проблему
shareef

Ответы:

14

Мне удалось решить это, вот шаги, которые я выполнил:

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

Во-вторых, я отследил источник запросов, которые выполнялись:

SELECT `mytable`.* FROM `mytable` WHERE `mytable`.`foreign_key` = 231273 LIMIT 1 

Первоначально я упустил из виду это как причину, потому что ни один из этих запросов, казалось, не занимал особенно много времени, когда я отслеживал вывод show processlist. Исчерпав другие возможности, я решил, что это стоит того, чтобы продолжить .... и я рад, что сделал.

Как вы можете видеть в выводе show processlist, эти запросы поступали с сервера utlility, который выполняет некоторые задания тактической утилиты, которые существуют вне нашего основного кода приложения. Вот почему они не проявляются медленно или не вызывают проблем в нашем новом мониторинге реликтов, потому что новый агент реликтов установлен только на нашем главном сервере приложений.

Сильно следуя этому руководству:

http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/

Я смог отследить эти запросы до определенного запущенного процесса на нашем сервере утилит. Это был немного кода ruby, который очень неэффективно перебирал около 70 000 записей, проверял некоторые значения полей и использовал их, чтобы решить, нужно ли создавать новую запись в «mytable». После некоторого анализа, который я смог определить, процесс больше не был необходим, поэтому его можно было убить.

Что-то, что усугубляло ситуацию, казалось, было 6 экземпляров одного и того же процесса, запущенного одновременно, из-за способа настройки задания cron и продолжительности каждого из них! Я убил эти процессы, и невероятно сильно сократилось использование нашего процессора со 100% до 5%!

WillJThomas
источник