Обновить

10 000 RPS и доступность 99,99%: как устроено шардирование PG в процессинге Яндекс Такси

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели12K
Всего голосов 34: ↑34 и ↓0+43
Комментарии10

Комментарии 10

Немного в сторону от статьи. Когда слова "такси" и "postgres" оказываются рядом, сразу вспоминается неудачная попытка Uber переехать на PG (https://yg140.servegame.com/en/companies/slurm/articles/322624/) Навскидку, больнее всего стрельнул update amplification в связке с частыми обновлениями координат и репликацией.
Наверняка в начале проекта вы знали про эту историю - почему в итоге выбрали PG, а не, например YDB?

Да, конечно, следим за опытом коллег. Но этот кейс не очень релевантный, так как процессинг не работает с координатами (этим занимается отдельный микросервис). Процессинг отвечает за цикл заказа, то есть за продвижения автомата заказа по стадиям, а это не очень интенсивная по update'ам задача.

Вопрос. В какой шард попадают новые записи? Насколько я понял из статьи, Вы рассказали, как данные распределены по шардам и как получить к ним доступ.

Второй вопрос. Что делается с данными, по которым заявка закрыта?

Выбор шарда делается по формуле из статьи. То есть вычисляется хеш от PK и от него номер шарда (из фиксированного кольца). В этом смысле схема довольно типичная. Отличие тут в способе выполнения решардирования.

В этой статье не рассказывается, но в реальности, хранилище разделяется на горячую и холодную часть (на основе YTsaurus).

а почему выбрали PostgreSQL ? Транзакции особенно не нужны, индексы, кроме PK не нужны
Глядя на статью - тут прямо просится какое-нибудь Key-value хранилище

Транзакции в такой все-таки нужны, чтобы атомарно работать с цепочкой событий. Но, в основном, выбор был скорее субъективный, так как была хорошая поддержка постгре в userver'e.

Интересно, а почему не ваша же ydb? Вроде по всем критериям подходит

На момент выбора много лет назад YDB еще не была достаточно зрелой технологией. А на текущий момент мы действительно переезжаем на YDB.

Можете подробнее рассказать, как именно копируете данные на новый шард? Репликация, силами приложения? Ведь данные постоянно обновляются, получается нужно:

1) остановить запись

2) скопировать все данные на новый шард

3) продолжить запись уже на новый шард

Понятно, что вы так не делаете, так как был бы большой простой. Но пока вы как-то копируете данные, эти данные обновляются на старом шарде и эти обновления нужно дослать на новый. А переключение записи на на новый шард можно сделать только убедившись, что все данные со старого шарда уже приехали. Иначе какой-нибудь UPDATE по условию обновит не все данные и будет не консистентно.

Я постарался раскрыть этот момент в разделе "Как поменять схему шардирования", но возможно не очень понятно получилось)

1) остановить запись

Вот этого не происходит, конечно же. Мы не можем просто взять и прервать обработку заказов, даже на несколько минут. Первым шагом мы учим узлы сервиса искать данные одновременно и в старом и в новом шарде. Благодаря этому, записи (как от сервиса, так и любую сбоку) можно делать в любой шард.

Но пока вы как-то копируете данные, эти данные обновляются на старом шарде

Чтобы такого не случилось, нужно перестать записывать новые данные в старый шард. Тогда после копирования старый шард будет "не свежее", чем новый.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
www.ontico.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия