Нужно ли прорабатывать масштабирование / шардинг при использовании облачных БД?
Есть собственное веб-приложение, которое (в нынешнем варианте) хранит данные в MySQL на том же сервере. Отлично работает в масштабе одного сервера при текущей (довольно невысокой) нагрузке, но возникает интерес, как оно будет работать, если вдруг внезапно на нем окажется в тысячу раз больше пользователей (и все таблицы в базе станут гораздо больше, каждый запрос будет более трудоемким да и сумма запросов на базу вырастет) ?
В принципе, каждый пользователь работает со своими данными, и взаимодействие между пользователями очень небольшое (для упрощения вопроса - будем считать, что его вообще нет). Поэтому сейчас рабочая идея - использовать горизонтальный шардинг, на каждом сервере держать столько пользователей, сколько он вытягивает (и все масштабирование состоит в том, чтобы при логине юзера перекинуть его на правильный сервер).
Если перейти, например, на AWS RDS (или посоветуете какие-то другие варианты?), придется ли как-то использовать похожие схемы (отдельные базы данных/шарды для каждой группы пользователей) или можно тупо не волноваться о нагрузке, она любую разумную нагрузку вытянет? (А суммы, которые придется за это платить, будут больше, чем если переобдумать схему масштабирования)?
Вообще, есть какие-то может быть хорошие гайды по легкому масштабированию для моего случая (когда каждый юзер работает исключительно со своими данными). В каждой таблице (коих немало) иметь поле user_id и по нему индексировать, и в каждом запросе указывать WHERE user_id=NNN ? Но это кажется довольно трудоемким и много шансов где-то в коде пропустить это условие. Напрашивается простое решение, чтоб у каждого юзера все его данные были в его базе данных (очень небольшой) и приложение работало с ней. Но тогда у нас будет очень много баз данных, и это будет немного некрасиво как-то. Может быть как-то можно получить аналогичный эффект сохранив простоту и надежность и малый риск ошибок?
Иван Шумов
@inoise Куратор тега Amazon Web Services
Solution Architect, AWS Certified, Serverless
Буду довольно резким, но зато без воды:
- облачные провайдеры не умеют в магию, только в создание ресурсов
- реляционные базы даже сегодня умеют только в вертикальное масштабирование
- да, думать приходится самостоятельно
- для облегчения жизни можно использовать Read Replicas, но готовьтесь к задержкам
- спайковую нагрузку реляционные базы выдерживать не умеют (да и остальные делают это из рук вон плохо)
Рекомендации:
- планируйте масштабирование
- научитесь понимать как используются ваши данные
- научитесь в микросервисы (и не по тому что это популярно, а по тому что так происходит изоляция данных)
- научитесь в другие виды баз данных, например то же DynamoDB, хотя если не вникать то можно огрести еще больше проблем
- вспомните что есть кэширование
- прочитайте что есть такие паттерны как CQRS
- научитесь в проектирование PWA (Progressive Web Applications)
- выбросите это все по тому что это будет очень дорого по итогу
Отлично работает в масштабе одного сервера при текущей (довольно невысокой) нагрузке, но возникает интерес, как оно будет работать, если вдруг внезапно на нем окажется в тысячу раз больше пользователей
Ответ очень простой - проверить с помощью stress test. То есть проанализировать текущий запросы к базе и симулировать х1000 кол-во пользователей. 90% что можно обойтись без шардинга, но опят покажет.
Плюс - с самого начала пишите аппликацию так, чтобы read-only запросы можно было направлять на отдельный ДБ сервер, это уменьшит нагрузку на master.
В целом, я с вами согласен, это все разумно. Но вот в моем случае, похоже, не подойдет:
1. Stress тест
Приложение сейчас хостится на VPSках. Соответственно, тут две стороны - с одной, на дешевой VPS в предел производительности мы точно можем упереться довольно легко. С другой - всегда есть решение в виде простого апгрейда тарифа на более мощную VPS. (Но мне, технически, конечно хотелось бы заранее знать, что архитектура у меня такая, что масштабироваться будет легко, даже когда дальше уже некуда апгрейдиться). А вот stress-тест сделать на облачной базе - можно ли? Или выйдет достаточно дорого (ведь нужно ее забить огромными объемами) ?
2. Read Only запросы
Увы, приложение по большей части собирает данные. Конечно, иногда и отдает тоже, но в обычном случае, наверное, на 100-1000 read есть один write, а у меня наоборот.
Хотя кто потом будет читать этот вопрос, для них это, возможно, будет правильными советами, сам так считаю.
Ярослав Поляков, без нагрузочного тестирования и тестов и мониторинга в принципе нельзя принять правильные решения насчет архитектуры. Ну или почти нельзя.
К счастью, в облаках сегодня поминутная или даже посекундная тарификация, так что все можно проверить очень недорого.
А вот stress-тест сделать на облачной базе - можно ли
Можно использовать или облачные сервисы loadimpact.com и т.д., или запускать свои скрипты для нагрузки на обычных линуксах ( locust.io и т.п.)
архитектура у меня такая, что масштабироваться будет легко, даже когда дальше уже некуда апгрейдиться
При какой-то нагрузке мы действительно упремся в возможности одно сервера базы данных для записи.
С реляционными базами масштабировать запись можно, но не очень легко.
С другой стороны, есть полезный совет "сначала запусти систему, а потом ломай голову что делать когда ты будешь Гуглом".
Написано
Иван Шумов
@inoise Куратор тега Amazon Web Services
Vitaly Karasik, правильное решение принять можно, конечно. Просто такая архитектура будет СТОИТЬ.
правильное решение принять можно, конечно. Просто такая архитектура будет СТОИТЬ.
Решение стоимостью $1M для моей домашней странички с посещаемостью 100 человек в месяц будет неправильным.
Написано
Иван Шумов
@inoise Куратор тега Amazon Web Services
Vitaly Karasik, Это зависит от бюджетов) люди часто путают слова правильная и подходящая. Правильная это когда она обеспечивает соответствие техническим требованиям, а подходящая - когда ещё и бизнес