Содержание

Масштабирование нагрузки web-приложений / Хабр

С ростом популярности web-приложения его поддержка неизбежно начинает требовать всё больших и больших ресурсов. Первое время с нагрузкой можно (и, несомненно, нужно) бороться путём оптимизации алгоритмов и/или архитектуры самого приложения. Однако, что делать, если всё, что можно было оптимизировать, уже оптимизировано, а приложение всё равно не справляется с нагрузкой?

Оптимизация

Первым делом стоит сесть и подумать, а всё ли вам уже удалось оптимизировать:

  • оптимальны ли запросы к БД (анализ EXPLAIN, использование индексов)?
  • правильно ли хранятся данные (SQL vs NoSQL)?
  • используется ли кеширование?
  • нет ли излишних запросов к ФС или БД?
  • оптимальны ли алгоритмы обработки данных?
  • оптимальны ли настройки окружения: Apache/Nginx, MySQL/PostgreSQL, PHP/Python?

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

Масштабирование

И так, допустим, что оптимизация уже проведена, но приложение всё равно не справляется с нагрузкой. В таком случае решением проблемы, очевидно, может послужить разнесение его по нескольким хостам, с целью увеличения общей производительности приложения за счёт увеличения доступных ресурсов. Такой подход имеет официальное название – «масштабирование» (scale) приложения. Точнее говоря, под «масштабируемостью» (scalability) называется возможность системы увеличивать свою производительность при увеличении количества выделяемых ей ресурсов. Различают два способа масштабирования: вертикальное и горизонтальное. Вертикальное масштабирование подразумевает увеличение производительности приложения при добавлении ресурсов (процессора, памяти, диска) в рамках одного узла (хоста).

Горизонтальное масштабирование характерно для распределённых приложений и подразумевает рост производительности приложения при добавлении ещё одного узла (хоста).

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

Архитектура приложения

Большинство web-приложений априори являются распределёнными, так как в их архитектуре можно выделить минимум три слоя: web-сервер, бизнес-логика (приложение), данные (БД, статика).

Каждый их этих слоёв может быть масштабирован. Поэтому если в вашей системе приложение и БД живут на одном хосте – первым шагом, несомненно, должно стать разнесение их по разным хостам.

Узкое место

Приступая к масштабированию системы, первым делом стоит определить, какой из слоёв является «узким местом» — то есть работает медленнее остальной системы. Для начала можно воспользоваться банальными утилитами типа top (htop) для оценки потребления процессора/памяти и df, iostat для оценки потребления диска. Однако, желательно выделить отдельный хост, с эмуляцией боевой нагрузки (c помощью AB или JMeter), на котором можно будет профилировать работу приложения с помощью таких утилит как xdebug, oprofile и так далее. Для выявления узких запросов к БД можно воспользоваться утилитами типа pgFouine (понятно, что делать это лучше на основе логов с боевого сервера).

Обычно всё зависит от архитектуры приложения, но наиболее вероятными кандидатами на «узкое место» в общем случае являются БД и код. Если ваше приложение работает с большим объёмом пользовательских данных, то «узким местом», соответственно, скорее всего будет хранение статики.

Масштабирование БД

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

Снизить нагрузку на БД можно разнеся её на несколько хостов. При этом остро встаёт проблема синхронизации между ними, решить которую можно путём реализации схемы master/slave с синхронной или асинхронной репликацией. В случае с PostgreSQL реализовать синхронную репликацию можно с помощью Slony-I, асинхронную – PgPool-II или WAL (9.0). Решить проблему разделения запросов чтения и записи, а так же балансировки нагрузку между имеющимися slave’ами, можно с помощью настройки специального слоя доступа к БД (PgPool-II).

Проблему хранения большого объёма данных в случае использования реляционных СУБД можно решить с помощью механизма партицирования (“partitioning” в PostgreSQL), либо разворачивая БД на распределённых ФС типа Hadoop DFS.

Об обоих решениях можно почитать в замечательной книге по настройке PostgreSQL.

Однако, для хранения больших объёмов данных лучшим решением будет «шардинг» (sharding) данных, который является встроенным преимуществом большинства NoSQL БД (например, MongoDB).

Кроме того, NoSQL БД в общем работают быстрее своих SQL-братьев за счёт отсутствия overhead’а на разбор/оптимизацию запроса, проверки целостности структуры данных и т.д. Тема сравнения реляционных и NoSQL БД так же довольно обширна и заслуживает отдельной статьи.

Отдельно стоит отметить опыт Facebook, который используют MySQL без JOIN-выборок. Такая стратегия позволяет им значительно легче масштабировать БД, перенося при этом нагрузку с БД на код, который, как будет описано ниже, масштабируется проще БД.

Масштабирование кода

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

Далее необходимо настроить балансировку нагрузки/запросов между этими хостами. Сделать это можно как на уровне TCP (haproxy), так и на HTTP (nginx) или DNS.

Следующим шагом нужно сделать так, что бы файлы статики, cache и сессии web-приложения были доступны на каждом хосте. Для сессий можно использовать сервер, работающий по сети (например, memcached). В качестве сервера кеша вполне разумно использовать тот же memcached, но, естественно, на другом хосте.

Файлы статики можно смонтировать с некого общего файлового хранилища по NFS/CIFS или использовать распределённую ФС (HDFS, GlusterFS, Ceph).

Так же можно хранить файлы в БД (например, Mongo GridFS), решая тем самым проблемы доступности и масштабируемости (с учётом того, что для NoSQL БД проблема масштабируемости решена за счёт шардинга).

Отдельно стоит отметить проблему деплоймента на несколько хостов. Как сделать так, что бы пользователь, нажимая «Обновить», не видел разные версии приложения? Самым простым решением, на мой взгляд, будет исключение из конфига балансировщика нагрузки (web-сервера) не обновлённых хостов, и последовательного их включения по мере обновления.

Так же можно привязать пользователей к конкретным хостам по cookie или IP. Если же обновление требует значимых изменений в БД, проще всего, вообще временно закрыть проект.

Масштабирование ФС

При необходимости хранения большого объёма статики можно выделить две проблемы: нехватка места и скорость доступа к данным. Как уже было написано выше, проблему с нехваткой места можно решить как минимум тремя путями: распределённая ФС, хранение данных в БД с поддержкой шардинга и организация шардинга «вручную» на уровне кода.

При этом стоит понимать, что раздача статики тоже не самая простая задача, когда речь идёт о высоких нагрузках. Поэтому в вполне резонно иметь множество серверов предназначенных для раздачи статики. При этом, если мы имеем общее хранилище данных (распределённая ФС или БД), при сохранении файла мы можем сохранять его имя без учёта хоста, а имя хоста подставлять случайным образом при формировании страницы (случайным образом балансирую нагрузку между web-серверами, раздающими статику). В случае, когда шардинг реализуется вручную (то есть, за выбор хоста, на который будут залиты данные, отвечает логика в коде), информация о хосте заливки должна либо вычисляться на основе самого файла, либо генерироваться на основании третьих данных (информация о пользователе, количестве места на дисках-хранилищах) и сохраняться вместе с именем файла в БД.

Мониторинг

Понятно, что большая и сложная система требует постоянного мониторинга. Решение, на мой взгляд, тут стандартное – zabbix, который следит за нагрузкой/работой узлов системы и monit для демонов для подстраховки.

Заключение

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

Вертикальное и горизонтальное масштабирование приложений

Вертикальное масштабирование — scaling up — увеличение количества доступных для ПО ресурсов за счет увеличения мощности применяемых с серверов.

Горизонтальное масштабирование — scaling out — увеличение количества нод, объединенных в кластер серверов при нехватке CPU, памяти или дискового пространства.

И то и другое является инфраструктурными решениями. Они требуются в разных ситуациях когда веб проект растет.

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

Возможности для масштабирования для серверов баз данных определяются применяемыми программными решениями. Чаще всего это реляционные базы данных (MySQL, Postgresql) или NoSQL (MongoDB, Cassandra и др).

Горизонтальное масштабирование для серверов баз данных при больших нагрузках значительно дешевле

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

  • перенести базу на более мощный сервер
  • добавить еще один сервер небольшой мощности с объединить машины в кластер

MySQL является самой популярной RDBMS и, как и любая из них, требует для работы под нагрузкой много серверных ресурсов. Масштабирование возможно, в основном, вверх. Есть шардинг (для его настройки требуется вносить изменения в код) и  репликация, которая может быть сложной в поддержке.

Вертикальное масштабирование

NoSQL масштабируется легко. С, например, MongoDB будет значительно выгоднее материально масштабироваться вертикально. При этом не потребует трудозатратных настроек и поддержки получившегося решения. Шардинг осуществляется автоматически.

Таким образом с MySQL нужен будет сервер с большим количеством CPU и оперативной памяти, такие сервера имеют значительную стоимость.

Горизонтальное масштабирование
С MongoDB можно добавить еще один средний сервер и полученное решение будет стабильно работать давая дополнительно отказоустойчивость.

Scale-out или горизонтальное масштабирование является закономерным этапом развития инфраструктуры. Любой сервер имеет ограничения и когда они достигнуты или когда стоимость более мощного сервера оказывается неоправданно высокой добавляются новые машины. Нагрузка распределяется между ними. Также это дает отказоустойчивость.

Добавлять средние сервера и настраивать кластеры нужно начинать когда возможности для увеличения ресурсов одной машины исчерпаны. Или когда приобретение сервера мощнее оказывается невыгодно.

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

Читайте про балансировку средствами Nginx и балансер HAPROXY.

Categories: Базы данных, Высокие нагрузки

Что такое масштабирование приложений и почему это важно

Что такое масштабирование приложений?

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

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

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

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

Преимущество заключается в том, что вы можете безопасно добавлять дополнительные функции в масштабируемые приложения, не беспокоясь о влиянии на производительность приложения. Основная цель любого приложения — обеспечить постоянно высокий уровень функциональности и производительности, независимо от того, есть ли у вас 10 пользователей или 10 миллионов.

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

Если масштабируемость не будет поставлена ​​в приоритет на раннем этапе, первоначальная популярность приложения станет неустойчивой по мере увеличения числа пользователей. Мало что заставляет пользователей отказываться от приложения быстрее, чем низкая производительность, медленная загрузка и сбои.

Сделайте ваше приложение масштабируемым

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

Важно понимать, с какой проблемой вы сталкиваетесь, и учитывать, что важнее всего, когда масштабируемость приложения является вашим приоритетом.

Хотя могут быть некоторые незначительные различия, обычно возможность масштабирования вашего приложения не будет зависеть от того, создаете ли вы мобильное или веб-приложение.

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

Выбор подходящей технологии

При разработке приложения помните о технологии, которую вы выбираете для своего проекта. Например, Node.js обычно является предпочтительной серверной технологией для легкой масштабируемости. Его также можно использовать как в мобильной, так и в веб-разработке.

Вам также необходимо определить, сколько серверов будет использоваться. Большинство служб облачного хостинга позволяют легко увеличивать и уменьшать мощность вашего сервера, но не всегда просто понять, как (или зачем) это делать.

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

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

Масштабируемая серверная инфраструктура будет использовать балансировщики нагрузки, чтобы перенаправить запросы с одного сервера на несколько серверов.

Балансировщик нагрузки действует как посредник между клиентом (интерфейсом) и серверами. Балансировщики нагрузки будут направлять трафик на соответствующие серверы таким образом, чтобы максимизировать эффективность сервера и сократить время загрузки.

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

Тестирование масштабируемости

Тестирование поведения приложения в различных условиях является наиболее важным аспектом обеспечения масштабируемости приложения. Существует длинный список способов проверить потенциал масштабирования приложения; однако эти три являются наиболее важными:

Нагрузочное тестирование относится к преднамеренному предъявлению требований к приложению и оценке его реакции. Это обширное тестирование поможет вам понять, как приложение будет работать, когда оно используется несколькими пользователями одновременно.

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

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

Почему важна масштабируемость?

Существует множество причин сделать масштабируемость приложения приоритетом. Ниже приведены некоторые из главных причин для разработки масштабируемого приложения:

Лучшее взаимодействие с пользователем

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

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

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

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

Экономит деньги

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

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

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

Вы должны быть готовы к росту, который приходит с достижением оптимального соответствия продукта рынку. Если вы все еще используете ту же недорогую инфраструктуру, на которой вы построили свой MVP, вы можете быстро столкнуться с проблемами производительности и потерять весь импульс, который вы так усердно создавали.

Для любого опубликованного приложения (т. е. не созданного для внутренних бизнес-целей) потеря пользователей означает потерю денег.

Стабильность приложений

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

Настройка функций

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

Обеспечьте лучшую производительность приложения

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

Обработка всплесков использования

Для большинства приложений количество пользователей (или объем данных, к которым пользователи обращаются) будет колебаться в течение дня, недели, месяца и т. д. Например, во время определенных событий (таких как праздники, специальные распродажи, Черная пятница и т. д.), ваше приложение может значительно увеличить число пользователей.

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

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

Одним из значительных преимуществ использования бессерверной инфраструктуры для управления масштабированием является возможность «включать и выключать» серверы. То есть с большинством бессерверных провайдеров вы платите только за потребляемую вычислительную мощность.

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

Положительные отзывы и отзывы пользователей

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

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

Зарабатывайте больше

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

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

Долгосрочный рост и успех

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

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

Масштабируемость приложения без кода

С точки зрения отсутствия кода можно легко увидеть такой инструмент, как встроенный бэкенд Airtable или Bubble, как вполне адекватный, но эти инструменты не созданы для масштабирования.

Даже продукт уровня MVP быстро достигнет ограничений вашей базы данных, начнет наблюдать ухудшение производительности и резкое повышение цен.

Backendless, с другой стороны, масштабируется.

Когда ваш рост достигает точки, когда план обслуживания приложений Backendless Cloud становится ограничивающим или слишком дорогостоящим, у вас есть возможность перейти на наши продукты без ограничений, Backendless Pro и Managed Backendless. Их можно установить на любые серверы, которые вы хотите, что дает вам полный контроль над возможностями сервера и, в свою очередь, масштабируемостью.

Бесконечно масштабируемая серверная часть

Backendless уникально предоставляет бесконечно масштабируемую внутреннюю часть, базу данных и серверную инфраструктуру для поддержки вашего мобильного или веб-приложения. Не требуя от вас написания кода, Backendless берет на себя кодирование и управление всей серверной инфраструктурой вашего приложения. Без серверов, которые нужно обслуживать, ваше время разработки теперь полностью сосредоточено на предоставлении бизнес-ценности вашим клиентам.

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

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

Заключение

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

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

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

Руководство разработчика по масштабированию приложения

Рон Пауэлл

Рон имеет опыт работы в космической физике, работая в команде Кассини, анализируя плазму, запертую в магнитосфере Сатурна. Сейчас он работает в компании CircleCI в Сан-Франциско, штат Калифорния, в качестве защитника разработчиков, создавая контент, который позволяет разработчикам быстрее создавать, тестировать и развертывать свои проекты. Ранее он был разработчиком-евангелистом в Samsung Electronics, Америка, где специализировался на производстве 360-градусного видео и разработке приложений для оборудования виртуальной реальности, носимых устройств и IoT.

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

Тем не менее, если ваше приложение будет успешным, в какой-то момент вы столкнетесь с необходимостью его масштабирования.

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

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

Что масштабировать и насколько далеко?

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

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

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

Если вы начинаете с монолитного приложения, то масштабирование оборудования может быть вашим первым выбором. Здесь вам просто нужно предоставить более быстрые машины с большим количеством процессоров и дополнительной памяти, чтобы код работал быстрее.

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

Именно здесь использование микросервисного подхода становится ценным: вы можете разделить свое приложение на несколько выделенных сервисов, которые затем докеризуются и развертываются в кластере Kubernetes.

Сначала автоматизируйте

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

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

В идеале все усилия по тестированию должны быть полностью автоматизированы и выполняться для каждой сборки. Ключевой частью этого являются конвейеры непрерывной интеграции. Непрерывная интеграция (CI) гарантирует, что изменения кода автоматически тестируются и объединяются в вашей основной ветке. Непрерывная поставка автоматически развертывает изменения в промежуточной или производственной инфраструктуре, но только в том случае, если она прошла непрерывные интеграционные тесты и контрольные точки.

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

Вы также можете автоматизировать настройку ресурсов. Если вы применяете подход «инфраструктура как код» (IaC) с такими инструментами, как Terraform от HashiCorp или AWS CloudFormation от Amazon Web Services, для автоматической подготовки и настройки серверов, вы даже можете протестировать и проверить код конфигурации, используемый для создания вашей инфраструктуры. Миграции также могут быть как минимум полуавтоматическими, что обеспечивает высокую степень гибкости.

Масштабирование хранилища данных

Одной из самых сложных для масштабирования вещей в любом приложении является база данных. Основная проблема объясняется теоремой CAP:

  • Непротиворечивость — каждое чтение получает самую последнюю запись или ошибку.
  • Доступность — каждый запрос получает ответ (без ошибок) без гарантии, что он содержит самую последнюю запись.
  • Допуск на разделение — система продолжает работать, несмотря на произвольное количество сообщений, отброшенных (или задержанных) сетью между узлами.

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

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

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

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

Масштабирование хранилища файлов

Подобно общему хранилищу данных, вам в конечном итоге придется подумать о распределенном хранилище файлов. Хранение файла на подключенном или даже встроенном диске по определению является узким местом. Хотя использование сетевого хранилища (NAS) или даже сети хранения данных (SAN) может быть полезно для локальных систем, вы также можете использовать облачные службы для этой распространенной задачи.

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

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

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

Оптимизация трафика

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

Ротация DNS устраняет ситуацию, когда только один IP-адрес получает все запросы, идущие к нашему домену. Однако даже в этом случае у вас есть несколько точек входа, но за ними по-прежнему стоят отдельные экземпляры приложения.

Другой метод заключается в использовании балансировщика нагрузки для разделения трафика между несколькими работающими экземплярами. Это еще одно из преимуществ использования облачного провайдера. У них есть сервисы, которые неявно используют балансировщик нагрузки, а также предлагают явный балансировщик нагрузки. Например, на AWS вы можете использовать Amazon Elastic Load Balancer для распределения входящего трафика.

Как правило, вы можете использовать программно-определяемую сеть и возможности оркестраторов ресурсов. Одним из примеров является встроенный балансировщик нагрузки Kubernetes. В качестве альтернативы рассмотрите специальное программное обеспечение, такое как HAProxy, для балансировки нагрузки.

Непрерывное масштабирование

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

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

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

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