Масштабирование веб-сайта без траты миллионов

Вы используете веб-сайт или веб-приложение, и оно быстро набирает популярность. Проблема: вы используете свой сайт на одном дешевом VPS. Он использует типичные компоненты, такие как MySQL или MongoDB, веб-сервер, такой как Apache или Nginx, некоторое хранилище и веб-фреймворк, такой как Python Django, или одностраничное приложение, использующее веб-сервисы. И теперь вам нужно масштабироваться, потому что все быстро разваливается. Что делать?

Вы запускаете свой сайт на дешевом VPS, и все разваливается. Что делать?

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

Использование CDN

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

Как работает CDN

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

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

Это упрощенное, но точное описание того, как все работает. Конечно, на самом деле за кулисами происходит гораздо больше.

Преимущества CDN

У такого подхода есть несколько очевидных преимуществ:

  • Это снижает нагрузку на исходный сервер (ваш дешевый VPS), потому что CDN будет обслуживать большинство активов непосредственно из кеша и никогда не попадет на исходный сервер.
  • Уменьшение пропускной способности на исходном сервере значительно
  • У вас будет быстрая загрузка, поскольку кэшированные страницы и ресурсы находятся поблизости, поэтому все загружаются намного быстрее, независимо от их местоположения. В качестве бонуса CDN применяют самые современные алгоритмы передачи, сжатия и (необязательно) минификации файлов.
  • В наши дни более быстрый сайт означает лучший рейтинг в Google и, очевидно, лучший пользовательский интерфейс.

Кроме того, есть и дополнительные преимущества, которые менее очевидны:

  • CDN очень хорошо обнаруживают DDoS-атаки и защищают ваш сайт от них.
  • Хороший CDN действует как брандмауэр приложений, блокируя подозрительные запросы или требуя капчи, чтобы снизить нагрузку от неизвестных и подозрительных роботов.
  • CDN может предложить вам автономную защиту: когда ваш сайт выходит из строя или работает слишком медленно, он все равно покажет пользователю кэшированную копию сайта.
  • Наконец, CDN действует как прокси для вашего сайта, поэтому пользователи никогда не узнают, где на самом деле размещен ваш сайт, если он правильно настроен. Фактически, вы можете запретить доступ к вашему веб-серверу любому IP-адресу, отличному от CDN, что значительно уменьшит вектор атаки на исходный сервер.

Когда CDN является правильным выбором?

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

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

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

Если вы используете WordPress (как это делают 40% веб-сайтов), у них также есть плагин, направленный на эффективное кэширование сайтов WordPress за 5 долларов в месяц, который я использую для размещения своего учебника по Python. Таким образом я могу кэшировать примерно 70% всех веб-запросов. Хотя это и не нужно, я все же могу обойтись дешевым VPS, улучшенная скорость загрузки заметна для Google и инструментов измерения сайта, таких как Маяк.

Для ясности: я не сотрудничаю с Cloudflare и мне не платят. Они просто потрясающие.

Масштабирование (добавление оборудования)

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

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

Если вы уже используете VPS или выделенное оборудование, вы можете обновить его. Наиболее важными аспектами любого сервера являются:

  • Мощность процессора: насколько быстры процессоры и, что более важно, сколько ядер?
  • Память: сколько оперативной памяти (ОЗУ) доступно?
  • Дисковое хранилище: обычно вам нужны быстрые SSD-накопители.

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

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

Распространение услуг на большее количество оборудования

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

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

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

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

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

Масштабирование (горизонтальная масштабируемость)

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

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

К счастью, мы живем в эпоху облачных вычислений, что позволяет нам стоять на плечах гигантов. Стало относительно легко создавать горизонтально масштабируемые системы с использованием сервисов, предлагаемых Microsoft, Google и Amazon. Проблема: это не совсем дешево! Итак, чтобы остаться верным названию статьи, я предложу еще несколько предложений, которые следует учитывать, прежде чем полностью прибегать к услугам облачных провайдеров.

Репликация и кластеризация

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

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

NoSQL

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

Если вы хотите узнать больше об Elasticsearch, обязательно ознакомьтесь с моими статьями об этом:

Использование гибридной модели

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

Облачная разработка

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

Контейнеры и микросервисы

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

Чтобы сделать это конкретным, давайте посмотрим, как будет упаковано приложение Python Django. Контейнер для такого приложения будет содержать:

  • Минимальный набор системных файлов Linux
  • Установка Python 3
  • Django и другие необходимые пакеты
  • Сам код

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

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

Докер и Кубернетес

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

Я уже писал о контейнерах и о том, как создать контейнерный Python REST API.

Преимущества облака

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

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

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