Предел прочности веб-сервиса, или как разогреть «холодный» кэш

e0635fab9339421eaadf5bf6fdb61b10.png

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


Предел упругости и предел прочности обычно проходят в школьной программе примерно вместе с загоном Гука (деформация растет линейно от приложенной силы), подчеркивая область применения этого закона. При работе с большими нагрузками (сотни и тысячи запросов в секунду) модель прочности физических материалов очень хорошо описывает поведение веб-сервиса под нагрузкой и характер его отказа в случае превышения нагрузкой «предела упругости».

Дальше я расскажу, как можно использовать эту модель, чтобы справиться с большой нагрузкой и решить задачу «прогрева» холодного кэша для веб-сервиса (новостного портала, интернет-магазина или SaaS), которую нам иногда приходится решать в случае полного сброса кэша сайтов.

«Предел упругости» веб-сервиса


Знание «предела» оптимальной работы веб-сервиса важно при обеспечении его стабильности. Понятно, что в случае DDoS этот предел может быть превышен в десятки, сотни или тысячи раз, но в случае ежедневной посещаемости всплески (уже достаточно большой нагрузки) будут только трех-пятикратными: т.е. достаточно иметь 5-кратный запас «прочности» по посещаемости веб-сервиса, чтобы гарантировать стабильную его работу в 99,9% случаев. Здесь и далее речь идет про дневную посещаемость 100 тысяч посетителей и выше.

Даже если у вас нет пятикратного запаса по прочности, то понимание, где конкретно находится «предел» стабильности, и как после прохождения этого предела сервис будет себя вести, — полезно. Кто осведомлен, тот вооружен.

Как найти этот предел? Он будет характеризоваться двумя особенностями:

  1. Время ответа сервера после прохождения предела будет расти быстрее, чем до него («сломается» линейность роста времени ответа сервера).
  2. Появятся сетевые или серверные ошибки (сервер (ы) не будет успевать обрабатывать все запросы).

Если у вас сейчас отсутствуют ошибки при работе веб-сервиса, то, скорее всего, вы еще не дошли до этого предела, и стоит воспользоваться любым генератором нагрузки (Яндекс.Танк, JMeter, ab, http_load, LoadImpact или любым другим), чтобы до этого предела дойти. Например, на графике ниже «перегиб» зависимости времени ответа от числа одновременных запросов наступает примерно при 45 запросах в секунду. Если при этом (или при чуть большей нагрузке) начинают возникать ошибки (502, 504, connect timeout) — это и есть искомый предел.

bf7bf490270548fdbb8133197e24c48b.png

Практическое использование «предела упругости»


В практических целях полученная величина нагрузки (когда веб-сервис еще работает нормально, но при небольшом — порядка 10% — повышении нагрузки уже начинают «заваливаться») может быть использована в следующих целях:
  1. Рассчитать нагрузку, при которой будет обеспечиваться KPI по времени ответа сервера (например, при 1000 запросов в секунду медианное время будет не больше 200 мс).
  2. Рассчитать увеличение серверных мощностей, которые будут гарантировать KPI по времени ответа (если сейчас он не достигается) или потребуются при росте нагрузки (например, с 1000 до 1500 запросов в секунду).
  3. Предупредить ситуации отказа веб-сервиса (если окажется, что ежедневные пики нагрузки уже превышают «предел упругости»): ведь при незначительном превышении нагрузки может произойти полный отказ в обслуживании.
  4. Получить расчетные значения нагрузки для ситуации «прогрев кэша» (обсудим чуть ниже).

Зная значение «предела упругости» веб-сервиса в случае линейного масштабирования делает работу с высокой нагрузкой полностью прозрачной и предсказуемой, минимизируем риски.

Полезно также знать реальный «предел прочности» веб-сервиса, но по опыту он не превосходит +30% от «предела упругости» (серверы достаточно быстро отказывают из-за лавинообразного роста нагрузки, когда небольшие задержки приводят к увеличение очереди запросов и превышению времени ожидания ответа уже для большинства входящих запросов).

«Прогрев кэша»


Возможна редкая, но очень неприятная ситуация: когда в случае массового обновления записей (страниц) необходимо их все максимально оперативно заменить на новые. Это может быть новый вызов кода, удаление вирусных вставок или исправление технической ошибки. А кэширование сайта позволяет работать в «зоне упругости» и гарантировать линейный рост времени ответа при увеличении нагрузки.

Резкий сброс кэша («прогрев») сразу выводит сайт в зону нестабильной работы или даже за пределы «предела прочности», поэтому недопустим. Существуют два (принципиально схожие) подхода для решения этой задачи.

Первый — это «прогрев» кэширующих серверов по очереди, предполагая, что «прогрев» каждого из них не выводит сайт из «зоны упругости». Характерный график такого «прогрева» показан ниже: число запросов резко возрастает, быстро возвращается к пониженному значению, потом ситуация повторяется до тех пор, пока все кэширующие серверы не будут более-менее «прогреты». Для описания этого процесса я использую термин «Каскадный сброс кэша».

48d7f64e2d4b496ab02232048c20519c.jpg

Возможна оптимизация описанного процесса, например, за счет синхронизации кэшей между серверами, в теории, можно добиться меньшего роста нагрузки при «прогреве» очередного сервера. Но на практике либо кэш серверов несколько различается (пересечение кэшей не более 20–30%), поэтому взаимное использование не дает кратковременного эффекта. Либо частота запросов к «прогретым» данным достаточно высока, и «прогрев» нового сервера происходит очень быстро (как на графике выше), поэтому синхронизация не требуется.

Второй подход — это физическое ограничение числа запросов (если они «прогревают» кэш достаточно медленно), чтобы при «прогреве» веб-сервис не выходил из «зоны упругости». В частности, в Mail.ru используют iptables, в Айри.рф используют IP Anycast. В любом случае для большинства пользователей веб-сервис оказывается на некоторое время недоступным, и по мере накопления кэша появляется для все большего числа пользователей (иначе сервис будет недоступен одновременно для всех из-за превышения «предела прочности»).

Какие меры используете вы при работе с высокой нагрузкой?

Комментарии (2)

  • 9 февраля 2017 в 21:06 (комментарий был изменён)

    0

    В моей ситуации трафик не регулируется плавно, можно либо снять либо пустить.
    Приходится прогревать кеш реплеем логов за последние 10–15 минут и после этого пускать траф.
  • 9 февраля 2017 в 23:04 (комментарий был изменён)

    0

    с загоном Гука (деформация растет линейно от приложенной силы)

    Добавлю, что идет речь о деформации упругого тела и пропорционально.
    По теме — считаю, что некое разумное ограничение количества запросов в секунду должно быть установлено на некешируемые элементы, на бекендах.

© Habrahabr.ru