Блог 1
1 неделю, 2 дня назад Увидели 3Категория
Теги проекта
Я нарисовал схему распределения баз данных PostgreSQL, разделив её по сервисам социальной сети. Схема постоянно обновляется и тестируется.
Схема нарисована на сайте diagram.net, имеет вкладки внизу страницы, каждая вкладка отведена под сервис. Это организация распределенной архитектуры, в сложившихся условиях не совсем удобна - связи между таблицами показывать неудобно, описание возможностей таблиц вводить неудобно, придётся как-то обходиться «тем что есть». Вообще, это видео я писал по просьбе заказчиков Juslaw LLC. Я был невыспавшийся, уставший, отвел мало времени на подготовку материала, потому смотреть такое видео не всем под силу. Отсюда и эта статья.
Пункт 1. Основные положения.
Сервисы бывают четырёх типов:
- Генеральные (пользователи и сообщества),
- Обычные (фото, видео, статьи),
- Служебные (utils, blockchain, neural_networks, super_frontend),
- Специализированные (finance, biznes, ads_service).
Общие принципы сервисов:
- Сервисы полностью самостоятельные в общей работе. Каждый знает про всех пользователей, может проверять их полномочия.
- Каждый сервис дублируется, все обновления динамически отсылает своим дублёрам.
- Для целей гарантированной синхронизации вводятся несколько служебных сервисов, задача которых - создавать очередь задач на пересылку общих данных в места назначения. Зарегистрировался ли пользователь, обновились ли общие данные - изменения отошлются куда следует и вернут ответ «удачно-не удачно». В случае ошибки соединения/синхронизации задача повторится, и так до удачной операции. Если сервис синхронизации будет занят/убит, задача перейдёт дублёру.
- Таблицы схемы также группируются по цветам/смыслу. Если таблица/цы содержат сведения других сервисов, то этот факт указывается сразу под названием таблицы/ц.
- Таблицы имеют название. Если оно закрашено зеленоватым цветом, то это таблица смежная, нужная для организации отношения много-ко-многим. Если поле таблицы заполнено желтым цветом, то это связь много-к-одному и обычно она названа по шаблону для понимания, куда она ведёт. Например, если такое поле называется user_id, то это связь с таблицей users.
- Поле таблицы может иметь знак «*», что значит обязательное. Знак «u» указывает на требование уникальности его значений.
- Почти каждая таблица имеет поле types, оно универсальное. Это нужно для динамического увеличения возможности объектов этих таблиц. Например, пользователь может быть активным, верифицированным, удалённым, закрытым, удалённым подавшим запрос на верификацию… Вариантов может быть много. Тем более, что мы хотим запомнить статус его, чтобы можно было откатить изменения обратно. Например, пост может быть редактированным, а потом удалённым, и если мы захотим восстановить пост, мы захотим вспомнить - какой статус был у объекта перед этим. Все эти чудесные вещи хранит поле types.
- Мы отлично понимаем архитектуру приложений и их распределение, поэтому знаем, как правильно разделить и дублировать возможности соцсети по сервисам. Так, модерация у каждого сервиса своя, что даёт возможность назначать управленцев специализированно. А вот уведомления вынесены в отдельный сервис, который доведён до ума максимально, и умеет сразу быть источником уведомлений, рекомендаций и новостей, быть местом прослушивания событий соцсети в реальном времени, регистрировать все моменты жизни платформы, настраивать получение/генерацию событий для каждого пользователя так тонко, как не умеет ни одна сеть в мире.
- Каждое создание пользователя, подписчика, сообщества, друга, объекта черного списка, забаненного пользователя, участника сообщества - тот час копируется на все сервисы, имеющие в своих базах данных такие модели. Это нужно для более твердой работы систем, а также для формирования приватности, так же самой мощной и безопасной, надежной и тонкой - в мире.
- Таблицы сервисов содержат объекты других служб в случае, если эти сервисы позволяют прикреплять что-либо в своих объектах. Один из ключевых моментом сети: можно прикреплять любые объекты до 10 штук в посты, задачи/карточки планирования и сообщения, до 2х в комментарии. Любые - это значит вообще любые, как снова не умеют никакие сети в мире.
- Приватность сервисов так же лучшая среди самых продвинутых соцсетей - если объект меняет видимость, такие же изменения сразу же применятся среди всех его копий в других сервисах. Потом, приватность можно тонко задавать в настройках как владельца объекта, так и списка объекта.
Пункт 2. Взаимодействие сервисов.
Вместо миллиона слов опишу парочку красноречивых примеров процессов в социальной сети.
Случай первый - регистрация пользователя:
- Сервис фронтенда ( к примеру) получает данные нового пользователя. Данные отправляются через открытое API на сервис пользователей.
- Сервис пользователя проверяет данные и создает новую запись в таблице users, также user_infos (информация о профиле), также по объекту списков друзей и подписчиков. Создаются сведения о геолокации, о настройках приватности, секретные данные (пароль, телефон, проверка подключения двухфакторной верификации).
- Сервис передаёт нужные данные одному из свободных синхронизационных сервисов, а тот проходит по всем адресам сервисов, имеющих копию пользователя. Сервис создает задачу в очереди и следит, чтобы данные ушли куда надо и вернули ответ об успехе операции.
- Данные затем передаются еще и сервису уведомлений, который регистрирует любые изменения всех объектов сети. Сервис создает объект новости «Новый пользователь зарегистрировался» и позволяет прослушивать и получать такие сведения всем, кто желает с этим знакомиться.
- Сервис сообщений создаёт менеджерский чат и приветственное сообщение, отсылает его специализированной копии пользователя на этом сервисе.
Случай второй - регистрация приложения API:
- На сервисе пользователей или сообществ можно создавать приложения, которые позволят работать с открытым API. При создании указываются сервисы, которые будут доступны для его работы, а также уровень доступа - читать данные сервиса или читать/писать их.
- На каждый сервис, указанный при создании, отсылается копия данных, чтобы создать там специализированный объект приложения.
- В дальнейшем любой запрос проверяется сервисом на токен, указанный в заголовке Authorization (bearer token). Если токен аутентификации, то он расшифровывается и можно понять id пользователя, если он есть. Если токен принадлежит приложению, проверяется - это приложение общее (к примеру, мой фронтенд сам будет таким приложением, получающим токены и передающим его на сервисы), или персональное (пользователя или сообщества).
P.S. Схема рабочая, проверенная. Она пережила 3 хорошие ревизии, и еще переживет незначительные изменения.