Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[SnowOne 2024] Екатерина Шевчук: Как мы перевоз...

jugnsk
April 30, 2024

[SnowOne 2024] Екатерина Шевчук: Как мы перевозили пользовательские профили на NoSQL

В докладе расскажу, как мы выделили микросервис для хранения данных пользователей и проведения CRUD операций над ними. Микросервис выделили из монолита процессинговой системы. Вместе с этим расскажу про то, как переехали с PostgreSQL на Cassandra, а также почему это сделали и какие профиты получили.

Основные моменты доклада:
Как устроена схема хранения профилей и объединения их в пользователей.
Что сделали для устранения Race Condition и Edit Conflict (так как данные клиента обновляются очень часто ).
Для чего используем Elasticsearch и как обеспечили согласованность данных между Cassandra и Elasticsearch.
Как разворачивали Cassandra и Elasticsearch.

jugnsk

April 30, 2024
Tweet

More Decks by jugnsk

Other Decks in Programming

Transcript

  1. КАК МЫ ПЕРЕВОЗИЛИ ПОЛЬЗОВАТЕЛЬСКИЕ ПРОФИЛИ НА NOSQL Екатерина Шевчук, старший

    инженер-программист, ЦФТ Художественное выпиливание данных клиента из монолита
  2. Разрабатываем процессинговую платформу Процессинг БД Создание профиля Создание профиля Получение

    продукта Заполнение профиля Поиск профиля Сохранение данных по продукту Обновление данных профиля n раз Поиск профиля Оформление продукта Обновление данных по продукту 3
  3. Разрабатываем процессинговую платформу  500-700 тыс. пользователей (1 200 –

    1 500/день) – таблица в PostgreSQL  10-15 млн. пользователей (7 000 – 10 000/день) – партиционированная таблица в PostgreSQL  35+ млн. пользователей (30 000 – 50 000/день) – отдельный микросервис с Cassandra 4
  4. Основные требования к сервису  Гибко нефиксированный формат данных 5

     Быстро - до 100мс большое количество запросов профилей трафик постоянно растет  Надежно потеря профиля недопустима простой сервиса неприемлем  Нужен поиск четкое совпадение по числовым данным по части фамилии
  5. Cassandra или PostgreSQL Cassandra PostgreSQL Горизонтальное масштабирование V X Отказоустойчивость

    в случае отказа мастера/ координатора V X Быстрое переключение на реплики V X Поддержка работы с json-форматом X V 6
  6. Разворачивание Cassandra  3 ноды, 1 дата центр  Разворачиваем

    через fluxcd (noops)  Реплицируем на 3 ноды  Anti affinity - под не должен работать на узле, если на этом узле уже работает один или несколько подов, удовлетворяющих правилу Label Selector 7
  7. Уровень согласованности запросов  ALL ждем подтверждения от всех 3х

    нод, что мешает отказоустойчивости  ONE  QUORUM 8
  8. Уровень согласованности запросов  ALL  ONE ждем подтверждения от

    1 ноды, что может привести к неконстистентности данных  QUORUM 8
  9. Уровень согласованности запросов  ALL  ONE  QUORUM ждем

    подтверждения от (n/2) + 1 нод, позволяет балансировать между отказоустойчивостью и консистентностью 8
  10. Реализация модели данных Модель данных для Cassandra строится от запроса

    к ним в отличие от реляционных БД user1 … user1 … user4 … user4 … user3 … user3 … user3 … user6 … user2 … user5 … user5 … user5 … 10
  11. Реализация модели данных Модель данных для Cassandra строится от запроса

    к ним в отличие от реляционных БД bank1 … bank1 … bank1 … bank1 … bank1 … bank1 … bank1 … bank4 … bank2 … bank2 … bank5 … bank6 … bank3 … bank3 … bank3 … bank3 … bank3 … bank3 … bank3 … bank7 … bank7 … bank7 … bank7 … 11
  12. Реализация модели данных Модель данных для Cassandra строится от запроса

    к ним в отличие от реляционных БД bank1 date1 … bank1 date1 … bank1 date1 … bank2 date2 … bank4 date1 … bank5 date2 … bank3 date3 … bank2 date1 … bank3 date1 … bank3 date1 … bank3 date1 … bank3 date1 … bank4 date2 … bank5 date3 … bank5 date1 … bank3 date2 … bank3 date2 … bank3 date2 … bank1 date3 … bank1 date3 … bank1 date3 … 12
  13. Реализация модели данных Типовые запросы  Создание и обновление профиля

     Получение данных профиля по pid  Сохранение связи пользователя с профилями и обновление идентификатора пользователя 13
  14. user uid user uid profile pid profile pid profile pid

    profile pid profile pid master_user master_uid 9 Модель данных
  15. profile pid profile pid profile pid profile pid profile pid

    master_user master_uid 9 Модель данных
  16. Реализация модели данных pid1 … pid3 … pid2 … pid7

    … pid9 … pid4 … pid5 … pid6 … persons persons persons uid2 pid2 uid4 pid6 uid_pid uid1 pid1 uid_pid uid3 pid4 uid3 pid5 uid_pid 14 pid8 … uid1 pid8 pid4 … pid5 … pid6 …
  17. 14

  18. Производительность на продакшене. Grafana поход в смежную систему 100 ms

    поиск elastic + cassandra Требования Требования Заголовки добавить 15 поиск elastic
  19.  Скорость благодаря шардам нагрузка распределена по кластеру расширяется «на

    лету» добавлением новых серверов  Надежность в случае сбоя узлов данные не потеряются, а будут перераспределены и поисковая система продолжит работу  Гибкость большое количество поисковых фильтров, возможность писать свои фильтры и анализаторы Соответствие требованиям Использование Elasticsearch 17
  20. Разворачивание Elasticsearch  3 мастер + дата ноды  4

    primary shards, 4 replica shards  Разворачиваем через fluxcd (noops) 18
  21. Поиск в Elasticsearch Для ФИО:  Строгий поиск Полное совпадение.

    Используем свой анализатор для поисковых терминов и для добавляемых в индекс данных (исключаем спец символы, е/ё).  Префиксный поиск По началу фамилии или имени. Возможность ускорения таких запросов с помощью index_prefixes параметра маппинга  Транслитерация При записи в индекс применяется фильтр, который переводит латинские символы в кириллицу. Ivanov -> Иванов Иван -> Иванов -> Иванченко 19
  22. Согласованность данных между Cassandra и Elasticsearch  Время индексации не

    должно влиять на время ответа на запрос по профилю  Важна конечная согласованность данных  В индекс добавляем всегда самые свежие данные Для доставки изменений идентификационных данных используется RabbitMQ 20
  23. Сервис RabbitMQ Индексер Обновление профиля индексация 21 Обновляем данные в

    индексе Схема доставки данных через RabbitMQ Elasticsearch Cassandra Сервис RabbitMQ Индексер Обновление профиля Кладём сообщение об обновлении профиля Достаём сообщение об обновлении профиля Достаём профиль
  24. Raсe condition + edit conflict Пришёл запрос на обновление профилей

    Пишем в PostgreSQL в таблицу блокировок pid’ы, блокируем эти записи. Если не смогли заблокировать хотя бы 1 строку с pid -> ошибка 1 2 3 4 5 Вычитываем версии профилей из Cassandra. Сравниваем версию профиля из Cassandra и версию пришедшего. Если версия не совпала -> ошибка Если версии совпали, то обновляем профили с увеличением версии Снимаем блокировку и удаляем записи в таблице блокировок 22
  25. Light Weight Transactions – ой   Нужно проверить существование

    профиля перед обновлением  У Cassandra есть прекрасная возможность – Light Weight Transactions 23
  26. Разрабатываем процессинговую платформу Процессинг БД Создание профиля Получение продукта Заполнение

    профиля Поиск профиля Сохранение данных по продукту Оформление продукта Обновление данных по продукту Создание профиля Обновление данных профиля n раз Поиск профиля Сервис профилей 24
  27. Выводы  Даже в самом начале разработки своего проекта не

    бояться денормализованных данных  Учитывать, что по мере роста сервиса при больших объемах данных на реляционке можно быстро сдуться, что может привести к поиску решения и переезду в авральном режиме  Эластик можно использовать не только в ELK стеке  Перед применением LWT несколько раз подумать, а точно ли они нужны и найти 10 способов обойтись без них 25