Архитектура кластера баз данных для географически распределенного проекта?

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

Допустим, мы разрабатываем клиент-серверное приложение, в котором все клиенты много пишут данных, но читают и вовсе в несколько раз больше. Чат/мессенджер/что-то подобное.
Я задался вопросом верной архитектуры бекенда для подобной задачи с точки зрения хранения данных, и накидал грубую схемку:
66e3f59e4cb8d028431282.png

Я приблизительно понял, как распределить нагрузку по чтению, плюс не обязательно делать это именно по регионам, это я так, для примера их привел. Но, грубо говоря, балансировщик нагрузки должен отправлять клиента на ноду, близкую к нему, например, где он с меньшей задержкой получит свои сообщения.
Допустим, так же - с записью, только чтоб не происходило проблем с одновременной записью с разных источников - сделал очередь сообщений. т.е. сбор потоков сообщений в одну кучу, а далее в "однопоточном" режиме запись в master базу. Хреново как-то получается, нет? Выходит, точка отказа - мастер бд + сервис очередей, и общая пропускная способность и скорость всего и вся зависит от этих двух частей. В чем я не прав и как сделать лучше?
по хорошему, надо и писать сначала в slave чтоб не было так что юзер отправил сообщение, но увидел его же только через, условно, 20 минут, когда оно пройдет весь путь от записывателя до считывателя в том же регионе. НО как в таком случае тогда это должно все выглядеть - вообще не представляю.
  • Вопрос задан
  • 2389 просмотров
Пригласить эксперта
Ответы на вопрос 1
Eugene-Usachev
@Eugene-Usachev
Если "чат/мессенджер/что-то подобное", будет лежать очень много данных. То есть профили можно сохранить хоть в Postgres + Redis (шардированный по регионам), и иметь вполне себе хорошую производительность. Проблема будет именно с сообщениями.

Если решать проблему по логике "почему бы не стремиться к 8 млрд пользователей", для профилей можно взять Aerospike или Tarantool. Оба решения имеют возможность шардирования по вторичным ключам, так что их можно разнести по разным регионам. Причём надо именно шардироваться, а не только реплицироваться. Таким образом, можно избежать "узких горлышек". В этом случае оба решения будут выдавать более миллиона запросов в секунду на один кластер с маленькой задержкой (скорее всего двухзначной в медиане) и не иметь единой точки отказа.

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

Выводы очень простые. Если "стремиться к 8 млрд пользователей" надо
1 - использовать нереляционные СУБД
2 - шардировать БД по регионам (тогда можно отказаться от очередей)
3 - использовать кэширование "горячих" данных
4 - использовать Write-Optimized СУБД для больших массивов данных.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы