Как организовать хранение данных для новостной ленты социальной сети?

Как организовать хранение данных для новостной ленты?
База данных Cockroach DB (ядро от PostgreSQL ). Основные сущности: пользователи, связь пользователей (друзья, подписчики), объекты (товары), сферы, подписки пользователей на сферы, посты, подборки.
Как я понял, есть два основных подхода:
1. Формировать ленту на лету из РСУБД. Реализацию такого подхода в данном случае не представляю возможным, потому что такой запрос должен будет затрагивать десятки таблиц с десятками join-ов, а итоговый набор записей будет содержать совершенно разнородные данные, для чего РСУБД не совсем подходит.
2. Готовить ленту для каждого пользователя отдельно. То есть возникает в какой-либо сфере событие, его нужно записать в ленту для миллиона подписчиков. Этот метод считаю более подходящим, но смущает два обстоятельства: нагрузка на запись в БД и объемы данных для хранения, хаос в разрешении всевозможных ситуаций: подписок, отписок, удалении постов и так далее.
Какую базу данных выбрать для реализации подхода 2 или ему подобных? Casandra и HBase или Aerospike, Scylla?
  • Вопрос задан
  • 425 просмотров
Решения вопроса 2
hint000
@hint000
у админа три руки
2. Готовить ленту для каждого пользователя отдельно. То есть возникает в какой-либо сфере событие, его нужно записать в ленту для миллиона подписчиков.
Беда этого варианта в том, что из миллиона подписчиков половина не заходили в ленту полгода+, ещё 200 тысяч не заходили месяц+, ещё 200 тысяч не заходили неделю+, а ваша БД всё это время бесполезно молотит для всего миллиона.

Здесь нет простого решения (в соцсетях вообще много непростого). Вам нужно как минимум комбинировать первый и второй метод (а может быть ещё и какой-то третий и какой-то четвёртый). И чтобы делать это оптимально (не требуя на миллион подписчиков столько же мощностей, сколько Вконтактик потратил бы на 10 миллионов подписчиков), потребуются действительно умные алгоритмы, а не только совет насчёт подходящей СУБД. Навскидку, для событий от друзей больше подходит второй метод, а для событий сфер - первый метод. Но это не точно. Можно применять второй метод только для тех, кто заходил не больше суток назад и т.п.
Ответ написан
Комментировать
@Arlekcangp
Разработчик, Лид, Архитектор ПО
Как уже указал hint000 первый вариант можно использовать только очень ограниченно. Для второго лучше взять что-нибудь документо-ориентированное или мульти-колоночное, что позволит денормализовать структуру данных. Т е вам нужно хранить некое представление "обобщённой ленты" (возможно отдельно для каждой сферы, что бы потом это можно было шардировать) и там будут лежать эвенты в каждом из которых может быть записано много разной информации. Возможно какие то данные пользователей, для формирования их персональной ленты в момент запроса. В принципе и на базе postgres можно организовать такую таблицу, c большим количеством полей, плюс postgres умеет класть в колонки json, что может помочь. Но в любом случае лучше применить паттерн CQRS и исходные данные хранить нормализованными, а при их изменении бросать эвент, который пойдёт в RabbitMQ или Kafka и будет обрабатываться пулом инстансов, обновляющих записи в лентах. А раз так, то там вообще можно взять что-нибудь типа elastic search. На чтение она должна быть очень быстрой.
хаос в разрешении всевозможных ситуаций: подписок, отписок, удалении постов и так далее.

Наибольшую боль, как мне кажется, доставит удаление/блокировка контента, т к оно подразумевает обновление большого количества информации во всех лентах куда попало удаляемое. Вы можете пойти на компромисс и сделать, как делают многие - удаленные посты приходят в ленте как заглушка. В этом случае нет необходимости удалять их идентификаторы из лент, достаточно просто не выдавать их при запросах по айди. Плюс не ломается пагинация и не нужно изобретать велосипеда с бесконечными прокрутками (хотя если маркетойды настаивают, что так лучше, то нам же легче ))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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