Комментарии 25
Самое главное не болеть манией величия и не начинать сразу с ориентира в миллионы пользователей и выстраивания соответствующей архитектуры. Миллионы, конечно, будут, но это будет позже, а продукт должен с чего-то начать. И его масштабирование — это эволюционный процесс: нельзя со 100% вероятностью предугадать, какие узлы системы окажутся более нагруженными, а какие менее.
первое правила стартапа-не надо начинать с масштабирования.
table field1,field2,field3,...field50
Потому что заказчик сам не знает чего хочет. А если настойчиво просить определиться, то можно и проект потерять. Потом, когда заказчик хоть немного определиться что хочет, можно структуру делать.
Что будете с этим делать?
накатывать логи, и надеяться, что мы не потеряем миг, между прошлым и будущим при фейловере;
если данные критичны — то ничего не тяряем, докатываем существующие логи на реплику, делаем переключение. Получаем простой сервиса, но зато не теряем данных.
Предупреждение? Увеличивать мощности на стороне реплики, внимательно следить за network lag и apply lag, настроить на них мониторинг.
— использовать принудительное чтение из мастера
— указывать в запросе требуемую метку целостности — в этом случае реплика может либо ждать, когда данные догонятся до нужной точки, либо перенаправить запрос на мастер.
Наверно для начала нужно уточнить насколько отстает на 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'ов, полля новые данные).
MySQL легко выдерживала тысячи QPS ещё на восьми ядрах
Какие именно QPS? Есть запросы которые выполняются 1ms, есть 500ms и даже очень много секунд, это зависит от кучи факторов, абстрактных QPS не бывает.
Какие именно QPS?
Автор описывает условный GramInsta, там и будут в основном запросы к
- ленте подписок
- конкретным фото / комментариям / лайкам
- профилям пользователей / постам пользователя
Ничто из этого не является тяжёлым запросом — селекты с парой джойнов по индексированным числовым полям и order by.
С учётом сказанного, если на сайте будет больше одного пользователя, почти всегда имеет смысл выделить уровень базы данных.
Перегнули палку в оценках, я бы начинал разговор об масштабировании от 100 rps, и то не факт.)
В большинстве проектов масштабирование нужно не для производительности а для надежности — т.е. репликация данных(чтобы не потерять), дублирование сервисов для быстрого обновления или переключения трафика при падении и т.п.
Вообще многое зависит от от выполняемых задач, если скажем у вас обычные проект 99% это CRUD с несложной бизнес логикой одна недорогая машина может выдерживать, сотни запросов в секунду, т.е. такое же или большее количество пользователей онлайн.
Например у https://stackexchange.com/performance ~300 rps в среднем. Вы можете видеть что у них 9 фронт серверов, но обратите внимание что средняя загрузка 5%, т.е. у них огромный запас в 95%.
Как масштабироваться с 1 до 100 000 пользователей