Как стать автором
Обновить

Как масштабироваться с 1 до 100 000 пользователей

Блог компании Дата-центр «Миран» Хостинг Разработка веб-сайтов *Серверное администрирование *Облачные сервисы
Перевод
Tutorial
Всего голосов 27: ↑27 и ↓0 +27
Просмотры 17K
Комментарии 25

Комментарии 25

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

первое правила стартапа-не надо начинать с масштабирования.

Более того, нельзя предугадать какие узлы системы вообще у вас останутся через пару лет, а какие вымрут или будут заменены на что-то иное.
Я на старте даже таблицы не нормализую.
table field1,field2,field3,...field50

Потому что заказчик сам не знает чего хочет. А если настойчиво просить определиться, то можно и проект потерять. Потом, когда заказчик хоть немного определиться что хочет, можно структуру делать.
Реплика отстает от мастера
Что будете с этим делать?
Синхронный коммит?
Что будем делать с лагами, которые зависят от самого медленного слейва?
Apple-way: показывать анимацию?
Идеи от любителя:
накатывать логи, и надеяться, что мы не потеряем миг, между прошлым и будущим при фейловере;
если данные критичны — то ничего не тяряем, докатываем существующие логи на реплику, делаем переключение. Получаем простой сервиса, но зато не теряем данных.

Предупреждение? Увеличивать мощности на стороне реплики, внимательно следить за network lag и apply lag, настроить на них мониторинг.
А за чей счет банкет? (увеличение мощностей)
Думал, что ответ очевиден, но окей:
— в месте, где я работаю, за счет клиентов;
— у компаний, которые только начинают, это происходит за счет инвесторов как правило.
Ну зачастую с отставанием реплики ничего делать и не надо. Далеко не всегда нужны строго актуальные данные. В тех же местах, где нужны актуальные данные есть как минимум два варианта:
— использовать принудительное чтение из мастера
— указывать в запросе требуемую метку целостности — в этом случае реплика может либо ждать, когда данные догонятся до нужной точки, либо перенаправить запрос на мастер.
С мастера читать любой дурак может
Ну похоже, что не любой. Вот кто-то не мог и задавал вопрос, что делать при отставании реплики.
Поиграемся с цветарабами (slave'ами).
Ничего

Наверно для начала нужно уточнить насколько отстает на 1 сек, на 10 сек, или на минуту, а может на 100 мс?) И что конкретно у вас за приложение, как используются данные вычитанные с реплицированного сервера.
Если у вас поиск по каталогу и какой то товар у одного пользователя появится в каталоге даже на 10 минут позже, это вообще не проблема.
А если у вас система реального времени где на основании информации вычитанной из реплики выполняются какие либо важные действия это совершенно другая ситуация.

Насколько отстает?
Что за проект?

Ответив всего на два этих вопроса, вы легко найдете ответ и на свой.
Как масштабироваться с 1 до 100 000 пользователей

StackOverflow при 10MAU(т.е. на два порядка больше) работает на 22 серверах, загруженных процентов на десять и иногда проводит стресс-тесты с запуском на двух машинах, так что цифры бы неплохо увеличить и задуматься над релевантностью этого текста среднему читателю.


В некотором смысле это напоминает нашу среду разработки: один инженер запускает базу данных, API и клиент на одном компьютере.

Один инженер запускает приложение поверх kubernetes / swarm, которое абстрагировано от физических машин и это заменяет пункты '10 пользователей: вынос БД в отдельный уровень' и '100 пользователей: вынос клиента в отдельный уровень', сводя их к добавлению машин в кластер. Шаг '1000 пользователей: добавить балансировщик нагрузки' тоже происходит по большей части сам за счёт round robin'а и nginx на edge.


10 000 пользователей: CDN

Разве закрыться Cloudflare — не шаг по умолчанию?


100 000 пользователей: масштабирование уровня данных

Немного покопавшись в метриках, мы видим, что CPU на сервере базы данных загружен на 80-90%. Мы на пределе.

Вы уверены, что это 100k пользователей? Даже достаточно примитивная MySQL легко выдерживала тысячи QPS ещё на восьми ядрах в 2017-м. В 2020-м, когда у Амазона можно взять машину с 96 физическими ядрами(IO bound с NVME-дисками быть достаточно сложно) за $4 в час, можно говорить о 100K+ QPS на чтение с одной машиной. Это миллионы пользователей онлайн и ближе к масштабам какого-нибудь фейсбука. На запись, очевидно, так не получится, но идея понятна.


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


В случае Database As A Service, о котором вы говорите в самом начале, эта проблема обычно уже решена за вас в некоторой мере.


Кэширование

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


Мы также хотим установить сервис мониторинга и аналитики вроде New Relic или Datadog

За New Relic не скажу, но Datadog не очень хорошо работал под нагрузкой ещё пару лет назад: я внедрял его на не очень сильном хайлоаде(до полутора тысяч запросов в секунду) и форвардящая нода давилась буквально сотней мегабит логов в секунду, а их облачный UI насиловал браузер неадекватными запросами(дэшборд с дюжиной графиков мог отправлять десятки запросов в секунду, возвращающих мегабайты json'ов, полля новые данные).

Разве закрыться Cloudflare — не шаг по умолчанию?

Github в том году дудосили — так они защитились, слив траффик в Cloudflare (что бы это ни значило). Но после дудоса выехали из-под зонтика обратно, ибо выходит дорого.

MySQL легко выдерживала тысячи QPS ещё на восьми ядрах

Какие именно QPS? Есть запросы которые выполняются 1ms, есть 500ms и даже очень много секунд, это зависит от кучи факторов, абстрактных QPS не бывает.
Какие именно QPS?

Автор описывает условный GramInsta, там и будут в основном запросы к


  • ленте подписок
  • конкретным фото / комментариям / лайкам
  • профилям пользователей / постам пользователя

Ничто из этого не является тяжёлым запросом — селекты с парой джойнов по индексированным числовым полям и order by.

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

Перегнули палку в оценках, я бы начинал разговор об масштабировании от 100 rps, и то не факт.)
В большинстве проектов масштабирование нужно не для производительности а для надежности — т.е. репликация данных(чтобы не потерять), дублирование сервисов для быстрого обновления или переключения трафика при падении и т.п.
Вообще многое зависит от от выполняемых задач, если скажем у вас обычные проект 99% это CRUD с несложной бизнес логикой одна недорогая машина может выдерживать, сотни запросов в секунду, т.е. такое же или большее количество пользователей онлайн.
Например у https://stackexchange.com/performance ~300 rps в среднем. Вы можете видеть что у них 9 фронт серверов, но обратите внимание что средняя загрузка 5%, т.е. у них огромный запас в 95%.

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