Перейти до вмісту
EuroVPSEuroVPS

Повільний сайт, вільний сервер: як знайти, куди йде час

Базу даних звинувачують першою, бо саме там відчувається очікування; вимірювання кожного рівня одного повільного запиту показує, де час витрачається насправді.

Автор EuroVPS EngineeringМашинне відділення

6 хв читання
У цій статті 4 розділів
Коротко
  • Повільна сторінка і зайнята база даних виглядають однаково за кількістю з'єднань, бо база даних є останньою синхронною зупинкою в більшості запитів і успадковує кожне зависання над собою.
  • Трасуйте один повільний URL рівень за рівнем: edge, хост, застосунок, потім база даних. Рівень, якому належить час, рідко є тим, що названий у тікеті.
  • Більша машина скорочує ту частину запиту, яка й так була короткою. Вимірюйте, перш ніж будь-що купувати.

Чому база даних є звичним підозрюваним

Коли сторінка сповільнюється, база даних є місцем, де симптом стає видимим першим. З'єднання накопичуються, список процесів заповнюється запитами в стані sending data, а slow query log починає зростати. Усе це реальне, і ніщо з цього не каже, куди пішов час. База даних стоїть наприкінці більшості шляхів запиту. Сторінка, яка викликає її двісті разів замість двох, worker, який тримає з'єднання відкритим, поки чекає на платіжний шлюз, кеш, який обходиться при кожному зверненні: кожне з цього проявляється як навантаження на базу даних, бо база даних робить саме те, про що її просять, частіше, ніж її варто було б просити.

Те саме стосується сервера. Хост під високим навантаженням є хостом, якому дають роботу. Чи є ця робота необхідною, є питанням, на яке графік навантаження не може відповісти.

Трасуйте один запит, а не весь сайт

Метод полягає в тому, щоб обрати один повільний URL і пройти за ним через рівні, вимірюючи на кожній межі. Почніть ззовні, з машини, яка не в тій самій мережі, і дозвольте curl показати, куди йде час до того, як надійде перший байт.

TERMINAL
$ curl -o /dev/null -s -w 'dns %{time_namelookup}  connect %{time_connect}  tls %{time_appconnect}  ttfb %{time_starttransfer}  total %{time_total}\n' https://www.example.com/slow-page

Якщо час до першого байта становить більшу частину загального, очікування на боці сервера. Якщо загальний час набагато більший за час до першого байта, сторінка важка або історія в шляху між відвідувачем і edge, і сервер не був частиною очікування.

На хості знімайте вибірку CPU, поки повільний запит у польоті, а не в простоюючу годину пізніше.

TERMINAL
$ mpstat -P ALL 1 5
$ vmstat 1 5

Сервер, який здебільшого простоює під час повільного запиту, без iowait і без steal, виправдав себе. Час витрачається на очікування чогось, а не на обчислення.

Потім застосунок. Більшість фреймворків уміють журналювати, на запит, кількість виконаних запитів до бази, загальний час, витрачений на них, і час, витрачений на вихідні HTTP-виклики. Увімкніть це для повільного URL. Два числа закривають суперечку: скільки запитів до бази видає одна сторінка і яка частина загального часу була витрачена цілком поза застосунком.

Нарешті база даних, з увімкненим slow query log і порогом, достатньо низьким, щоб упіймати те, що має значення.

TERMINAL
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 0.2;
SET GLOBAL log_queries_not_using_indexes = ON;

Прочитайте журнал за вікно повільного запиту. Жменя запитів, кожен з яких триває секунди, є проблемою бази даних. Тисячі запитів по мілісекунді кожен є проблемою застосунку, у якій звинувачують базу даних.

Шаблони, які проявляються при вимірюванні

Коли рівні розділені, причина зазвичай набуває однієї з кількох форм.

Endpoint, що викликається в циклі. Front end, який повторно отримує той самий ресурс при кожній зміні стану, або сторінка, яка видає один запит на рядок замість одного запиту на сторінку. База даних відповідає на кожен виклик швидко; проблемою є кількість.

Синхронний виклик до когось іншого. Платіжний провайдер, ERP, API доставки, менеджер тегів, що стоїть на шляху запиту за довгим таймаутом. Сервер простоює все очікування, а сторінка настільки повільна, наскільки повільна найповільніша третя сторона, від якої вона залежить.

Кеш, який обходять. Заголовки, що забороняють кешування на сторінках, які не змінюються, або відсутність edge-кешу перед анонімним трафіком, який ніколи не був динамічним.

Пули, розміри яких вгадали. Пули workers, з'єднань і буферів, задані завеликими так само часто, як замалими. Пул, значно більший за те, що машина може обслужити паралельно, перетворює чергу на штовханину.

Справжнє вичерпання є останньою формою, і коли вона з'являється, вона зазвичай є наслідком однієї з перших трьох. Те, що машині чогось забракло, є кінцем історії, а не початком.

Що змінює більший сервер

Додавання ядер чи пам'яті скорочує ту частину запиту, яка обчислювала. Якщо ця частина й так була малою, сторінка не стає швидшою; очікування переїжджає разом з нею. Цикл досі циклить, третя сторона досі витрачає свій час, кеш досі обходять. Оновлення також ховає вимірювання, яке знайшло б причину, бо графік, що був червоним, тепер бурштиновий, і тікет закривається.

Саме тому ми трасуємо, перш ніж давати пропозицію. Здорова платформа залишається нудною, а робота полягає в тому, щоб знайти рівень, якому належить час, навіть коли цей рівень стоїть вище за все, чим ми керуємо, і повернути вимірювання, яке вказує на рядок.

Прямі відповіді

Чому мій сайт повільний, якщо серверу вистачає CPU і RAM?+

Бо час витрачається на очікування, а не на обчислення: на цикл викликів, на сторонній API на шляху запиту, на кеш, який обходять, на запит, що виконується тисячі разів. Простоюючий сервер під час повільного запиту є сильним натяком, що очікування живе вище за обладнання.

Чи зазвичай повільний сайт є проблемою бази даних?+

База даних зазвичай є місцем, де очікування видно, бо вона є останньою синхронною зупинкою в запиті й успадковує кожне зависання над собою. Чи є вона причиною, вирішує slow query log: кілька повільних запитів вказують на базу даних, потік швидких вказує на застосунок.

Чи варто купити більше RAM або більший сервер, щоб виправити повільний сайт?+

Не до трасування. Потужність скорочує обчислювальну частину запиту. Якщо запит чекав, а не обчислював, оновлення переміщує очікування замість того, щоб його усунути, і ховає графік, який знайшов би причину.

Як відрізнити проблему застосунку від проблеми бази даних?+

Рахуйте й міряйте час. На запит: скільки запитів до бази, скільки часу загалом, скільки часу у вихідних викликах. На запит до бази: slow log. Якщо час на запит низький, а кількість висока, застосунок питає надто часто. Якщо час на запит високий, проблема в запиті, індексі чи схемі.

Принесіть нам свій найповільніший URL, і ми протрасуємо його рівень за рівнем до рядка, якому належить час.

Поговоріть з інженером.

Поговоріть з інженером

Ви дійшли до кінця.

Застосуйте прочитане на практиці

Що ви запускаєте?

Розкажіть нам про навантаження, трафік і вимоги до відновлення. Почніть з конструктора сервера або обговоріть деталі з інженером.

Написано інженерами, які будують і експлуатують інфраструктуру, про яку йдеться.
Поговоріть з інженером
XIn

Залишилося 6 хв