LINUX.ORG.RU

Пишем мессенджер. Подумаем об архитектуре БД для черновиков.

 


0

2

Есть мессенджер, в котором несколько разных распределённых баз, ничего не знающих друг от друге и не имеющих распределённых транзакций. Одна база - это, условно, как отдельный постгрес, а распределённая - это значит пошарденая по какому-то ключу. Реально там не постгресы, а скорее рэдисы. То есть, каждая база - это несколько каких-то редисов. У баз есть кодовые имена, типа:

  • MESSAGE - хранит сами сообщения; это особая база, она хранит каждый чатик как вектор объектов Message, больше ничего не умеет. Зато умеет зверски быстро отдать любой подинтервал любого чатика или вставить мессагу в середину чатика длиной миллиард месаг за микросекунду.
  • LIKES - хранит лайки к чему-то, может вернуть число лайков под каким-то объектом по его ID, больше ничо не умеет. Ну и умеет гарантировать, что ты не лайкнул что-то 2 раза. Реакции короче.
  • ACCOUNT - хранит профили юзеров. Пароли там всякие, ID фотки аватара и что-то такое.
  • SESSION - хранит куки или какие-то залогиненные сессии; Буквально это хештаблица sid=uid.
  • ATTACH - хранит инфу про аттачи; буквально хештаблица attach_id = (кодовое filename в хранилище файликов, автор аттача, когда запощено, тип аттача, что-то ещё..)
  • ATTACH_HASH - хранит хеши известных файлов, дедупликация аттачей, чтобы 2 раза одно и тоже не хранить
  • ATTACH_UID - обратный индекс для аттачей uid=[список всех аттачей этого юзера, чтобы можно было все экстремистские материалы сразу майору слить когда террориста поймали]
  • LIBRARY - информация про чатики или группы или каналы. Длинный профиль и настройки чатика. Буквально хештаблица chat_id = (структура данных про этот чатик рассказывающая - кто создал, когда, полное имя, полное описание, аватарка, флаги разрешённых действий с чатиком, список модеров и владельцев и прочая херобаза)
  • CONTACTLIST - контактлисты юзеров. Ты в чатик зашёл, тебе его в контактлист захерачили. В мессенджер вошёл - твой контактлист вычитали и тебе вернули, чтобы ты мог в свои чатики или в свои контакты смотреть.
  • и т.п. Разных баз около 20 под каждый пук.

И тут мы захотели сделать черновики. Ну короче, запилили базу DRAFT и запилили функционал в клиента и в сервер. Набираемое в поле ввода периодически отправляется серверу, сервер это кладёт в отдельную базу «DRAFT». Когда клиент умер и переподключился, то открыв данный чатик ему подгрузят из DRAFT что он там набирал и он может продолжить. Всё как-бы хорошо, но есть приколы.

  1. Раньше постинг мессаги предполагал на backend 1 запрос в базу MESSAGE - запостил и готово, а теперь 2 запроса - надо ещё удалить эту мессагу из DRAFT.
  2. Если DRAFT упала и там что-то было, а ты уже запостил, то потом внезапно клиенту восстанет из ада старый черновик. Возможно это чем-то хорошо, ну мол лучше данные сохранить, чем потерять, но всё равно странновато.

Потом возникла идея, которую надо обсудить.

  1. Выкинуть базу DRAFT и сохранять черновик в базу MESSAGE в отдельную табличку в той же шарде. Когда юзер постит, сделать хитрее: выполнить в базе особо хитровыдуманную атомарную команду «move» которая атомарно-транзакционно переместит черновик как он есть в таблицу сообщений (тут предполагается, конечно, что мы доводим черновик перед этим до состояния финальной мессаги, то есть досылаем в черновик те изменения, которые юзверь сделал после последнего SAVE_DRAFT и до MSG_SEND). В постгресе такой «move» бы наверно делался как небольшая транзакция вида "BEGIN; вставить в MSG результат подзапроса из DRAFT; delete from DRAFT; COMMIT;). Решается сразу проблемы (1) и (2).

Но тут возникла такая приколюха:

  1. Если раньше база MESSAGE была нагружена на запись только тем, что туда постили финальные мессаги, то теперь каждые 2 секунды туда будет апдейт черновика от каждого кто печатает. То есть, это сразу кратный рост нагрузки в разы. Прям в разы. Потому что для каждого «поста» финального сообщения в чатик, который совершался и раньше, теперь этот пост ещё льётся нам каждые 2 секунды в эту базу в отдельную табличку апдейтом. Теперь если посмотреть на пишущую нагрузку в базу MESSAGE то добавление финальных сообщений в неё - это теперь не основная нагрузка, основная - куча апдейтов черновиков.

Короче как лучше не понятно. Ужирнить MESSAGE и забить болт или всё таки юзать схему с отдельной базуней DRAFT?



Последнее исправление: lesopilorama (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

отличается что набираемый текст будет передаваться сразу, без нажатия пользователем enter/send/save (это spy-ware) и не будет истории на серверах. И тем что эта функция побочная, она не нужна в основном функционале.

На Телеграме так есть. Отправить не нажимаю, у собеседника появляется «Печатается», после этого открываю с сотового и вижу этот текст в поле ввода (неотправленный).

monk ★★★★★
()
Ответ на: комментарий от monk

На Телеграме так есть. Отправить не нажимаю

вот отчасти потому его текущие проблемы :-)

микс текстового и видео-чата. Нельзя транслировать и сохранять текст как видео, в процессе набора

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Нельзя транслировать и сохранять текст как видео, в процессе набора

Тогда почему mail.ru не забанен? И Яндекс.Документы?

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)