О том, как сайт Have I been pwned? масштабировался под высокой нагрузкой и сколько это стоило (<$25)

Это перевод оригинальной статьи 10 things I learned about rapidly scaling websites with Azure от Troy Hunt

На картинке изображен график роста траффика, который облачные адепты по всему миру продают в виде одного из сценариев, когда эластическое масштабирование имеет высокую ценность:

Sessions going from barely anything to almost 12k an hour almost immediately

Это график посещений сайта Have I been pwned? (HIBP), на который в один момент стал обслуживать со ~100 сессий в час до… 12000 сессий в час. Практически мгновенно.

Это случилось на неделе в сентябре, когда траффик буквально увеличился в 60 раз. 10 сентября – 2105 сессий, 11 сентября – 124036 сессий. Интересные вещи происходят, когда нагрузка увеличивается так резко, так быстро. Так что мне захотелось поделиться с вами несколькими вещами, которые я узнал – что было сделано мной хорошо и что следовало улучшить.

Да, кстати, почему траффик так резко вырос? Потому что новости повсюду сообщали о том, что 5 миллионов учетных записей Gmail были взломаны. Конечно, на самом деле они имели в виду, что 5 миллионов адресов неизвестного происхождения, почти полностью на gmail.com были слиты на русский форум с соответствующими паролями. Но это никак не помешало большому количеству людей сойти с ума по всему миру и прийти на HIBP для того чтобы проверить были они или нет теми “счастливчиками”, данные которых утекли в сети. Это дало мне возможность испытать уникальный опыт и поставило передо мной интересные задачи, которые следовало решить. Позвольте мне пройтись по некоторым задачам.

1) Измеряйте все как можно раньше

Знаете ли вы, что вы не сможете исправить что-то, что вы не в состоянии измерить? Да, на самом деле очень сложно понимать, что происходит в настоящее время, если у вас нет возможности измерять разные вещи. У меня было три по-настоящему важных инструмента, которые мне очень помогли:

Google Analytics: это источник того графика, который вы видел выше и я активно использовал этот инструмент во время того, как нагрузка увеличивалась, практически в реальном времени изучая как много людей находилось на сайте в определенный момент времени (по крайней мере тех, которые не блокировали у себя трекинг):

Google Analytics showing 1175 people on the site right now

New Relic: это абсолютно крутой инструмент и если вы до сих пор не используете его в своих облачных веб-сайтах, то предлагаю вам скорее прочитать статью Скотта Хансельмана о том, как начать использовать сервис бесплатно.

NewRelic web transactions response time graph

На самом деле, он был самым первым по-настоящему полезным инструментом не только для определения того, насколько серьезную нагрузку я испытывал, но и для определения возможных причин, влияющих на производительность системы. Я снял этот график сразу после масштабирования, он показывает множество ошибок в промежутке с 2:30. Кроме того, график показывает большое увеличение метрики CLR time, И как вы можете убедиться, дела пошли гораздо лучше сразу после 6:00.

NewRelic был так же инструментом, который был доступен из любой точки с любого устройства. Приложение для iPad просто отличное, содержит панели информации, которая сообщает всю необходимую информацию от общего числа запросов, до запросов к определенным страницам. Особенно полезными данными оказались тайминги браузеров и сервера с подробностями типа сетевыми задержками и рендерингом DOM (NewRelic добавляет некоторые клиентские скрипты, которые позволит получать такие данные). Эти данные в дальнейшем показывали мне насколько сильно нагружен сервер:

NewRelic dashboard on the iPad

Мониторинг Azure: вы получаете функции мониторинга Azure бесплатно, они доступны вам в портале управления Azure. Мониторинг позволяет осуществлять наблюдение за рядом метрик, за которые вы в конечном итоге расплачиваетесь, так что наблюдать за ними действительно важно:

Azure's website monitoring graph

Они так же хорошо ложатся в сервис уведомлений платформы (Azure Alerts), о чем я расскажу совсем скоро.

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

2) Настройте уведомления

Я понял о возникшей драме на утро четверга из-за того, что мой почтовый ящик переполнился уведомлениями – их были дюжины и все они выглядели следующим образом:

Azure alert for high CPU usage

Это уведомление от Azure для метрики CPU и я так же настроил подобное для уведомления о превышении некоего порога общего числа запросов. Все эти уведомления относятся к метрикам мониторинга, про которые я говорил выше и они дают мне знать о том, что с моим сервисом происходит что-то необычное.

Другие уведомления были от NewRelic, особенно полезными были уведомления о полной нагрузке сервиса (NewRelic периодически пингует конечные точки и проверяет доступность подключения к БД и хранилищу), так же полезны были уведомления о деградации индекса “Apdex”:

Alert from NewRelic for a low Apdex

Apdex – это способ NewRelic измерения уровня пользовательского удовлетворения от работы сайта и самое крутое в нем то, что он собирает в себе все показатели начиная от работы базы данных и очередей запросов и до CLR time и просто говорит “будет ли пользователь доволен временем ожидания ответа?”. В этот вопрос входит и настоящий пользователь тоже – и тот который загружает ваш сайт через плохое соединение с другой части мира и тот, который работает через скоростной 4G рядом с самим ЦОД. Я не буду глубоко погружаться здесь в этот вопрос, только покажу как выглядела картина моего сервиса утром в четверг:

NewRelic Apdex showing a big drop during high load

На самой низкой отметке более 25000 пользователей были смоделированы и из них слишком большое число имело отзыв о работе сайта как “Неприятный” просто потому, что система была слишком медленной. Она работала – но слишком медленно. В любом случае, основное в этом всем то, что я был очень рад иметь проактивные уведомления о том что происходит с моим сайтом.

Но из всего этого следует следующий вопрос – почему система замедлилась? Разве я не имел “облачное масштабирование”? Не я ли недавно с удовольствием рассказывал какое в Azure классное масштабирование сервисов? Да, все так, за исключением одной проблемы…

3) Изначально задайте максимальный лимит масштабирования

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

Setting the instance count in Azure

Видите проблему? Да, я оставил максимальным значением числа экземпляров число “3”. Вот и все. Это и есть причина того, почему мой индекс “Apdex” стал неприемлемым, так как Azure делала именно то, что я ей указал. Глядя на это теперь, мне мое решение представляется глупым. Это ограничение существует для того чтобы вы не масштабировались на максимальное число экземпляров автоматически и через месяц после этого не получили шокирующий для себя счет за облако. Однако, когда у вас есть уведомления, такое ограничение себя становится бессмысленным. Позвольте объяснить:

Azure использует поминутную тарификацию. Поднимите экземпляр, используйте его полтора часа и выключите его, вы заплатите только за 90 минут потребления. Независимо от размера экземпляра, 90 минут будут стоить вам для любых целей меньше доллара. Если вы настроили уведомления, например, на непривычно высокий уровень запросов (это настраивается на портале управления Azure), вы будете знать о том, что ваше окружение было масштабировано почти сразу как только это случится, а возможно и даже перед тем как это случится. Это зависит от того, как вы настроили уведомления. Имея в виду такие преимущества, я с большим удовольствием выберу масштабирование сервиса до 10 экземпляров с оплатой лишних пары долларов, чем боль моих пользователей от работы с одним единственным экземпляром.

На самом деле, кажется странным, почему вы вообще можете не захотеть масштабироваться? Я имею в виду, вы же не скажете “Вау! Мой сайт на самом деле очень успешен, я думаю, что мне стоит оставить моих пользователей страдать еще чуть-чуть”. Некоторые люди могут беспокоится о влиянии таких вещей как DDoS-атаки, но это те вещи, которые выявляются достаточно быстро с помощью инструментов, которые я описал выше.

Так что мой совет – увеличьте до максимума свой уровень автоматического масштабирования сервиса и перестаньте беспокоится (я поговорю о денежной стороне чуть позже).

4) Масштабируйтесь заранее

Горизонтальное масштабирование (добавление экземпляров) может происходить автоматически, но вертикальное масштабирование (увеличение размера каждого экземпляра) – это ручной процесс. Оба процесса дают вам возможность увеличить вычислительную емкость, но вместе с тем, они добиваются этого разными путями. В этой статье о Azure я рассказал, что при переходе с экземпляра размером small на экземпляр размера medium удваивается как производительность так и цена. Переход с medium на размер large удваивает параметры снова и так далее – чем больше экземпляр, тем больше вы получаете.

Когда я обнаружил проблему с масштабированием из-за лимита в три экземпляра, я не только увеличил его до 10, но и изменил размер экземпляров со small до medium. Почему? Частично потому, что я не был уверен, что десяти small-экземпляров будет достаточно, но кроме того и потому что я хотел выделить больше ресурсов на обработку высокой нагрузки как можно скорее и побыстрее вернуть свой сайт к нормальной работе.

Другая причина состоит в том, что экземпляры большего размера под нагрузкой не будут исчерпывать свой ресурс так быстро. Обратите внимание на график:

Very fast change in the number of simultaneous sessions

Здесь видно что в полночь было 727 сессий, затем 753 в час ночи, в два часа уже 9042 и 11910 в три часа ночи, Это существенное изменение за очень небольшой период времени. Возвращаясь к вопросу о производительности, когда Azure масштабирует сервис, добавляя экземпляр, она еще некоторое время смотрит как обстоят дела (это время настраивается), а затем при надобности добавляет еще один экземпляр и так далее. Период паузы между добавлением экземпляра был установлен в 45 минут, что давало Azure массу времени для того чтобы понять как идут дела с нагрузкой и решить нужно или нет добавлять еще один экземпляр. Но так как траффик рос так быстро дополнительный small-экземпляр мог исчерпать свои ресурсы очень быстро, за гораздо меньший период, чем период паузы. Medium-экземпляр предоставил мне гораздо больше пространства для маневров.

Конечно, large-экземпляры дали бы мне еще больше мощности. Как то раз, наш двухлетний ребенок проснулся с плачем в час ночи пятницы и моя жена пошла его проверить. Будучи заботливым родителем, я решил проверить как поживает мой сайт HIBP и увидел примерно 2200 запросов в минуту с поднятыми четырьмя medium-экземплярами. Я изменил размер экземпляров на large и пошел обратно спать – больше перестраховался. (И да, с человеческим ребенком тоже было все в порядке!)

5) Облако Azure потрясающе устойчивое!

Очевидно, что сайт HIBP получил жестокий удар, у меня нет никаких сомнений. Если чего и следует ожидать, когда сайт переполняется запросами, так это того, что его работа начнет сбоить. Очевидно, одним из таких сбоев является замедление сайта и в самом деле Apdex четко это показывает. Другим сбоем может стать то, что сайт под нагрузкой начнет сыпать ошибками различного вида, многие из которых NewRelic может определить. И вот что было обнаружено:

Error rate at 0.0078%

Ключевое на рисунке – это значение в правом верхнем углу – процент ошибок 0.0078% или другими словами, это означает, что всего 1 запрос из 128000 приводил к ошибке в течение недели. Конечно, это значение базируется только на тех запросах, которые в принципе были получены сайтом и были обработаны облачным мониторингом NewRelic. Красные линии на рисунке отражают момент, когда сайт HIBP определялся как неработающий (упавший) (NewRelic снаружи подключается к сайту и проверяет работает он или нет). Нужно сказать, что я видел отчеты NewRelic о том, что сайт “упал”, но после этого имел возможность зайти на сайт через браузер без проблем прямо в период “падения”. Функция пинга, которой сервис проверяет сайт является примерной константой в 2.66 запросов в минуту, так что вполне возможно, сайт работал в момент, когда отмечено что он “лежал” (или “лежал” во время, когда говорится что он работал!):

Ping throughput rate at 2.66RPM

Неизбежно, некая часть запросов могла возвращаться с ошибками тайм-аута гейтвея (gateway timeouts), но факт того, что он продолжал работать так хорошо под такой нагрузкой, впечатляет.

6) Худейте заранее

Поделюсь с вами одним маленьким магическим трюком – более быстрые сайты масштабируются быстрее. Я знаю, откровение, не так ли?! :)

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

The present day HIBP website

Имея в виду наше желание масштабировать конкретно этот сайт как можно больше, давайте посмотрим на все запросы, которые направляются на haveibeenpwned.com в порядке загрузки:

4 requests being made to HIBP

Погодите – что?! Ага, всего четыре запроса. Причина по которой число запросов к сайту настолько небольшое в следующем:

  1. Я использую публичный CDN для всего, что только возможно. Я расскажу об этом подробнее отдельно, так как это очень важная тема;
  2. Я использую сервис Azure CDN для всех иконок взломанных (pwned) компаний. Это позволяет перенаправить запросы с сайта распределить их по всему миру;
  3. Все скрипты JavaScript и стили CSS упакованы и минифицированы. Это хорошо для конечных пользователей, которым придется делать меньше HTTP-запросов и хорошо для сайта, который будет пересылать меньше байт с каждого запроса. Было бы неплохо поместить их в CDN тоже, однако иметь возможность перезаписывать их при редактировании кода и позволять автоматически отправлять их через ASP.NET для меня намного важнее, учитывая как часто я меняю разные вещи.

Но конечно, все это может быть улучшено еще больше. Для начала, 32 КБ – это слишком много для favicon – вдвое больше всего другого контента, который отдается с домена! Изначально я сделал ее в виде 64х64 пикселя, чего более чем достаточно, а в идеале и вовсе может быть в виде 48х48. Так что я изменил иконку и убрал половину размера, а затем поместил ее в CDN, добавив тег link в head моего шаблона. Так еще один запрос и другие 32 КБ кода исчезли для моих клиентов. Это изменения вступит в силу в следующий раз, когда я опубликую измененный код.

Другой вещью, которая позволила похудеть сайту стал факт того, что не было практически никакой работы на сервере для создания страницы – только контроллер возвращающий представление. На самом деле, для формирования списка утечек использовалась база Azure SQL Database (SQL Azure), но даже с этим, вот как выглядела пропускная способность:

Response time for the SQL Azure database

Хм… – почти линейная. Ага, все потому что данные закэшированы и на самом деле запрашиваются домашней страницей из БД один раз в каждые пять минут. Это показывает нам то, что база данных значительно изолирована от высокой нагрузки. И на самом деле, самый затяжной запрос – это тот, который проверяет присутствие в базе данных пользователя, который подписывается на уведомления. Выглядит этот пиковый запрос так:

Requests for checking a notification user in the DB

Это соответствует только 3.43k запросам за два часа или же одному ленивому запросу в две секунды. Конечно, мне повезло в том, что мой сайт такого типа, который не требует частого обращения к БД и это многое меняет, когда нагрузка серьезно увеличивается. В таких случаях множественные подключения к БД могут быстро увеличить время ответа на запрос пользователей.

Так, если я не часто запрашиваю данные из БД, то как же на самом деле я проверяю взломанные учетные записи? Детально я рассказывал про это в моем предыдущем посте Working with 154 million records on Azure Table Storage – the story of “Have I been pwned?”, но если говорить коротко, то ответ – хранилище Azure Table Storage. Как описано у меня в блоге, это хранилище чрезвычайно быстрое в сценариях, когда вам необходимо просто выбрать строку по ключевому полю (например, email в моем случае), именно так как я структурировал данные на сайте HIBP. Это привело к тому, что моя статистика использования Table Storage выглядела следующим образом:

Table Storage usage

Два больших пика тут выглядят странно. Они вызваны тем, что я загрузил 5 млн. учетных записей GMail утром четверга и затем еще 5 млн. записей mail.ru 1 млн. записей yandex.ru на следующий день. Хотя сайт и был загружен в это время, загрузка 11 млн. записей никак не повлияла на доступность или производительность сайта.

Однако, из таблицы мы можем узнать некоторые полезные данные, например, средние задержки на сервере были в районе 7 мс. Семь миллисекунд! На самом деле, даже при огромной нагрузке эта цифра оставалась на одном уровне и была даже ближе к 4 мс. Единственная вещь, которая как вы можете убедиться, на самом деле изменялась – это процент успешных запросов. Причина этому простая – когда кто-то искал данные по email и получал ноль результатов, такой запрос считался в статистике “проваленным”.

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

7) Крадите пропускную способность у других!

Итак, как было описано выше, я использовал CDN для все, что только возможно. В том числе jQuery,  Bootstrap (CSS и JS) и Font Awesome. Выглядит это следующим образом:

Requests to external CDNs

Это прекрасная возможность увеличить производительность. Во-первых, это позволяет снизить число запросов к HIBP и уменьшить поток данных на 69 КБ для каждого нового посетителя. Ок, я бы мог упаковать эти JS и CSS файлы с другими, которые используются на сайте и получить такое же число запросов, но это не позволило бы мне сократить объем передаваемых данных, за которые я плачу деньги. Умножьте эти 69 КБ на примерно четверть миллиона посетителей в самый жаркий период и речь сразу пойдет о 16 ГБ передаваемых данных, на которых я сэкономил.

Наконец, все дело просто в скорости. Большая работа была проведена мной для уменьшения индекса Apdex, что включает в себя так же все перечисленные выше шаги. Польза публичных CDN не только в том, что они располагают данные ближе к пользователю, так как размещаются у крупных провайдеров (типа jQuery на серверах Google), но и в том, что скорее всего запрошенные данные уже были закэшированы у пользователя в браузере, так как были получены с других ресурсов, которые так же используют эти CDN. И нет ничего более быстрого, чем работа из локального кэша!

На самом деле, говоря про геораспределенные вещи может возникнуть вопрос, почему я не использовал сервис Azure Traffic Manager и не распределил свой сайт по разным ЦОД Azure по всему миру. Я мог бы сделать это очень просто (как описывается по ссылке) и я скорее всего сделаю это в будущем, но на тот момент мой сайт успешно работал на базе единственного экземпляра. Добавление еще одного узла, скажем в Европе, удвоило бы мои расходы на сайт. Но уверяю вас, если когда-нибудь я столкнусь с подобной постоянной нагрузкой, когда одного экземпляра просто недостаточно, то самым умным будет использовать именно Traffic Manager для увеличения возможности масштабирования. Это не только ускорит сайт для тех пользователей, которые будут ближе ко второй локации сайта, но и буквально удвоит мои возможности масштабироваться под серьезную нагрузку, имея в виду наличие второго ЦОД для моих нужд.

8) Всегда, всегда будьте готовы к быстрому обновлению кода

Когда имеешь дело с нагрузкой, которая растет быстро и неожиданно, необходимо иметь возможность и реагировать так же быстро. Одним из моих решений на ранних стадиях было убрать кусок кода, который я опубликовал несколькими днями ранее. Этот код должен был запускать отдельный поток и отправлять уведомление в сервис Google Analytics для регистрации вызова API, того что я ранее отслеживал только на стороне клиента (и это приводило к тому, что я пропускал регистрацию вызовов, которые происходили напрямую). Я не был уверен, насколько эти дополнительные запросы к Google Analytics с сервера могут иметь влияние на производительность, так что я решил убить их.

И тут появляется важная вещь: так как этот код был в состоянии готовом к выпуску, все что мне нужно было сделать – это внести изменение и отправить его на GitHub для того чтобы произошла магия автоматической публикации (функция Azure Web Sites – прим. перев. ):

Azure deployment history showing a release

Этот процесс действительно требует минимум движений. Да, существует небольшое замедление работы сервиса (обычно NewRelic сообщал мне о том, что скорость стала снизилась на период времени в одну минуту), но это очень просто способ внести изменение и он не влияет каким либо ощутимым образом на людей, которые используют сервис. Основное преимущество здесь в том, что я могу вносить изменения и получать их в продакшне по первому желанию. У меня были и другие идеи того, как мне уменьшить нагрузку с помощью изменений в коде и единственным барьером к их применению могла бы стать невозможность вносить изменения так быстро и без влияния на окружение под высокой нагрузкой.

Конечно, частично моя возможность выпускать новый код так быстро основана на том, что я использую функцию автоматической сборки. Около четырех лет назад я написал цикл статей You’re deploying it wrong! и на самом деле воспевал значение автоматизации. И сейчас меня передергивает, когда я вижу как люди размещают свои сайты через сборку в Visual Studio или, прости боже, заливая изменения с использованием FTP. Существует миллион причин использовать для размещения кода такие инструменты как GitHub и сервис Azure Kudu. Просто используйте их и никогда не возвращайтесь к прошлому!

9) Экспериментируйте с размером экземпляра сайта и параметрами автоматического масштабирования для поиска вашего идеала

Одна из вещей, которую я узнал во время всего этого упражнения и которая бесконечно меня порадовала, это то что процесс масштабирования вверх и вниз, горизонтально и вертикально не имеет ни малейшего влияния на производительность во время перехода (речь идет про преимущества масштабирования сайтов Azure WebSites – прим. перев. ). Мне было бы гораздо сложнее решить, скажем, когда делать масштабирование вверх на более мощный экземпляр, если бы этот процесс мог привести к прерыванию работы сайта. На графиках можно увидеть небольшие пики, но я не регистрировал сброшенных запросов или чего либо еще, что могло бы сказать о том, что пользователи сталкивались с неработающим сайтом.

К ночи пятницы ситуация стала понемногу приходить в норму. Я все еще использовал экземпляр сайта размера medium, и функция масштабирования уменьшила число экземпляров всего до одного. Затем изменила до двух. Потом опять до одного. Затем, ок, это стало выглядеть так (каждый цвет – это отдельный логический экземпляр сайта):

Fluctuating instance counts

Поведение было похоже на игрушку Ё-Ё. Среднее потребление CPU для обоих экземпляров падало ниже требуемой границы, что приводило к удалению одного из них. Однако, потребление CPU единственным экземпляром было выше нижней границы, что в свою очередь приводило обратно к добавлению экземпляра. Это было не самым лучшим поведением и в самом деле, каждый раз как система масштабировалась вниз до одного экземпляра NewRelic сообщала мне что Apdex слегка снижался. Было очевидно, что моя нижняя граница для CPU была слишком высокой и мне необходимо было изменить параметры, чтобы убедиться, что вычислительные мощности не уменьшались вдвое и это не привело бы к проблемам.

Здесь возникает очередной вопрос: когда вы убираете один из двух экземпляров приложения вы теряете 50% мощности. На самом деле, это большой скачок для одного изменения и при всех равных, очевидно, что четыре малых экземпляра дадут вам больше гибкости в настройке, чем два средних. Имея это в виду, я увеличил нижний уровень числа экземпляров до двух, так что этот вопрос перестал меня беспокоить. Самое страшное, что у меня могло произойти – это 30% падение мощности при масштабировании с трех до двух экземпляров, что все таки лучше потери половины мощности сразу.

Даже в субботу утром с сайтом происходили разные вещи – масштаб изменялся на один-два экземпляра. Я поправил некоторые настройки по уровням масштабирования и скорее всего это привело к некоторому нестабильному поведению. Напоминаю, что Apdex был приемлемым и мои пользователи были счастливы, так что мне не требовалось такое частое изменения масштаба.

Наконец, я вернул настройки на их начальные значения для увеличения масштаба:

Default settings for scaling up

И эти настройки для удаления экземпляра:

Default settings for scaling down

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

Мне был хотелось заметить, что все приложения отличаются. Существует определенный набор триггеров, которые показывают изменения в нагрузке, которые вероятно могут потребовать масштабирования и различные точки, когда это должно происходить. Вам постоянно приходится балансировать на нежелании получить медленный сайт с одной стороны и увеличения затрат на сайт с другой. Нагрузочное тестирование тоже сможет рассказать вам о многом, да, в предыдущей статье я проводил тестирование сконцентрированное на только определенном аспекте (только API) и на самом деле существует больше подходов для тестирования реальных случаев и поведения пользователей. Но ничего не сравниться с системой в реальном несфабрикованном окружении под старой доброй реальной нагрузкой!

10) Расслабьтесь, это всего лишь деньги!

Теперь, вопрос, который люди спрашивают после рассмотрения всех деталей – как много все это стоило? Все это масштабирование недешевое, ведь так? Давайте посмотрим, что нам скажет портал билинга.

В начале, посмотрим как масштабирование изменялось за весь период безумства:

image

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

Я использовал три типа ресурсов, которые применялись под необычными условиями. Первое – это “маленькие” стандартные часы веб-сайтов. Обычно с этим просто – я использую их весь день на единственном экземпляре, так что плачу за 24 часа в день. Вы можете увидеть на графике как эта метрика не менялась в первые дни:

Small standard website usage

Метрика прыгает вверх 10 числа и еще больше 11 числа, а затем 12 числа становится относительно низкой. После этого момента я в основном работал на экземплярах размера medium, так что расходы перешли на другой уровень. Основное, что можно извлечь из этого графика – это то, что я потребил 25.80 стандартных часов малых веб-сайтов, которые я обычно не потреблял. Числа, которые превышают 24 часа в один день означают несколько одновременно запущенных экземпляров.

Посмотрим на график использования medium. Обычно я не использую экземпляры размера medium, только 11 и 12 числа я воспользовался ими и потребил некоторое количество ресурсов:

Medium standard website usage

Все указанные часы могут рассматриваться в виде дополнительной нагрузки, так что мы видим 55.03 часов medium экземпляров.

Перейдем к большим экземплярам. Я масштабировался на них в час дня 11 числа из-за своей паранойи, а затем перешел назад на medium:

Large standard website usage

На самом деле работало несколько больших экземпляров одновременно, так что понятно что они съели 20.34 часа за период времени в 7 часов. О, кстати, Azure выставляет счета очень точно, так что эти 20.34 часа на самом деле были представлены в счете как 20.34083 часа (связано с поминутной тарификацией в Azure – прим. перев. ).

Давайте сложим все и посчитаем затраты:

Размер экземпляров Цена за час  Количество часов Стоимость
Small $0.10 25.08 $2.51
Medium $0.20 55.03 $11.01
Large $0.40 20.34 $8.14
Всего     $21.65

Да. Это все – $21.65. Основываясь на моем потреблении кофе, это несколько дней потребления капучино. На самом деле я потратил даже больше на кофе во время, когда мой сайт HIBP обрабатывал запросы сотен тысяч посетителей, чем я заплатил за хостинг!

Но конечно есть и другие затраты, такие как потребление сети и транзакции с хранилищем. Но они не имеют значения. Стоп – это еще почему!? Дайте мне показать вам мой уровень загрузки сети:

Chart of outbound data usage

Я использовал дополнительные 20 ГБ в период высокой нагрузки, посмотрим сколько это стоит:

20GB of data costing $1.80

Меньше чем половина капучино. И тоже самое касается затрат на транзакции с Table Storage – они даже не приближаются к тем цифрам про которые мы тут говорим.

Проще говоря, на все про все я потратил <$25. И именно поэтому я написал статью Donations, why I don’t need them and why I’m now accepting them for “Have I been pwned?” – потому что затраты настолько низкие, даже когда вы получаете внезапную пиковую нагрузку подобную моей. Я получил немного пожертвований во время работы сайта, которые с лихвой окупили все затраты на обработку нагрузки. Но как объясняет моя статья, затраты, которые я на самом деле ощутил не касались моего кармана!

Заключение

Больше всего из описанного мной случая я убедился в том, что широко распространенное “высокое масштабирование” может быть крайне дешевым. До такой степени дешевым, что я изменил поведение сервиса так, чтобы больше число экземпляров добавлялось как можно раньше (я увеличил лимит до 10). И теперь, если я вижу четыре или более работающих экземпляров, которые обрабатывают быстро растущую нагрузку я увеличиваю и размер экземпляров тоже заранее. Я предпочитаю принимать решение о снижении уже выделенных мощностей для сохранения денег по ходу дела, чем внезапно обнаружить, что мои посетители стали испытывать трудности с сайтом из-за высокой нагрузки.

Другая важная вещь – это само приложение и devops. Очень важно иметь заранее оптимизированное приложение, которое может быть быстро опубликовано не только для описанных сценариев, но и в нормальных условиях. Меня коробит от некоторых приложений, которые мне приходится видеть с изъянами в дизайне, которые приводят к массивным затратам вычислительных мощностей с самого начала их работы: из-за отсутствия индексов в БД, захламленного session state, отсутствия клиентской оптимизации – все эти веди уменьшают возможность масштабирования и это означает, что вам придется делать это значительно раньше и за большие деньги.

Но что я люблю больше всего в сервисах типа Azure и вещах из этой статьи, та это то, что они делают высокое масштабирование сайтов по-настоящему доступным. Любой может перейти на портал прямо сейчас, выделить себе ресурсов, что всего несколько лет назад потребовало бы привлечение ИТ-профессионалов, которые работаю с серверным оборудованием, долгого ожидания и значительных финансовых затрат. То, что вы можете делать сегодня по цене капучино – действительно вдохновляет!

Полезные ссылки