Как стать автором
Обновить

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

RPO в худшем случае: 160 Мб.

Можно подробнее, в каких ситуациях могут быть потеряны данные в такой архитектуре?

В статье это опущено, но есть параметр synchronous_commit. У нас он выставлен в off. Плюс используется асинхронная потоковая репликация, поэтому некоторые данные до реплик могут не доехать, особенно если лидер будет перегружен.

Поясните, пожалуйста, каким образом настройка maximum_lag_on_failover оный RPO гарантирует? Я даже не о плюс-минуc loop_wait/2 seconds из документации, а как вообще оно механически работает?

Когда лидер стал недоступен, у нас есть LSN-ы реплик, есть последний зафиксированный LSN лидера в DCS (в Consul, например). Под капотом в PostgreSQL LSN - смещение в журнале транзакций в байтах.

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

А вот если у нас все реплики отстанут более чем на 160 мегабайт, то это уже совсем другая история :)

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

Практически все сервисы у нас используют "асинхронный подход". У нас есть буквально пара сервисов (связанные с биллингом), для которых мы настраиваем синхронную репликацию (ценой уменьшения производительности).

RTO и RPO обычно определяются как золотая середина между стоимостью потери данных или простоя и доступности сервиса. Чем меньшее время простоя сервиса обеспечивает защита, тем дороже она стоит. 

В local-first архитектурах потери данных в принципе не происходит и это ничего не стоит. На вашей картинке это будет в центре координат:

:

А где предполагается хранить local-first базы для случая avito?

Там же, где и remote-first.

В облаке, что ли? Можете схемку набросать, допустим, тут https://mermaid.live?

Интересно, я один не понимаю смысла писать 100500ю статью на тему "Мы используем Patroni, он классный"?

А как вы решаете проблему, когда нужно записать в базу и сразу сделать чтение данных с учетом записанных? Если писать только в мастер, а читать из слейвов, то есть риск не получить данные. Если и писать и читать из мастера - то не получится подразмазать нагрузку. Как вы решаете такие проблемы, особенно с учетом синхрониус коммит офф? Буду благодарен за инфу :)

Никак не решают, читания-писания уровнем выше скорее всего реализованы.

Все верно, при таком подходе на репликах не всегда возможны актуальные данные.

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

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

Это active - active cluster?

Да. В статье это опущено, но у нас есть самописный механизм для балансировки - db_discovery. Этот механизм, в рамках PostgreSQL, предоставляет DSN до текущего лидера. Когда лидер сменяется, DSN меняется до нового лидера с минимальной задержкой.

а CockroachDB или yougadb не рассматривали? тот же PostgreSQL только нормально масштабируется

Сейчас мы занимаемся активным внедрением CRDB на платформу Avito, плюс есть положительный опыт у сервиса, который сам поддерживает и администрирует CRDB.

Изучали YDB (Open-Source который) в прошлом году, но он не смог прижиться у нас.

Понятно. А можете сказать почему YDB не прижился?

В 2022, когда исследовали, столкнулись со следующим:

  • Не прижился к текущей топологии K8s (невозможно работать вне k8s, например пользователям подключаться);

  • Проблемы документации: либо что-то не соответствовало действительности, не описаны некоторые подводные камни (например, перед созданием БД требовалось инициализировать хранилище (storage));

  • Невозможно создавать и администрировать ролевую модель в YDB.

Возможно, это уже давно все поправили, но мы сейчас все силы бросили на внедрение CRDB.

Понятно. Спасибо!

используете ли pg_rewind и если происходит переключение, то занимаетесь ли восстановлением данных, если на момент переключения был replication lag?

Да, пока у нас используется pg_rewind, но подумываем от него отказаться.

В общем случае, если был replication lag более 160 Мб и у нас имеются бэкапы WAL-ов (лидер успел передать WAL-ы перед своим отказом), то реплики будут восстанавливаться (используя restore_command) до тех пор, пока replication lag станет менее 160 Мб.
Если бэкапов WAL-ов нет и реплики не могут догнать экс-лидера, то предстоит действовать по ситуации.

спасибо за ответ, я немного про другое имел ввиду) pg_rewind затирает данные и были ли ситуации когда такое происходило, насколько я понимаю, там восстановление только руками можно выполнить. То есть произошел failover и произошло переключение, отработал pg_rewind и затёр разницу в wal чтобы работала синхронизация с новым мастером

А, если мы говорим про откат мастера до реплики для переключения TimeLine, то да, для этого автоматика у нас использует pg_rewind, сами ничего не делаем.

а ещё мы используем RAID

Интересно было бы узнать поподробнее, какая реализация используется? Программный/аппаратный, какая конфигурация себя зарекомендовала?

Исторически сложилось, что для PostgreSQL используется аппаратный RAID 5. До недавнего времени использовался аппаратный RAID 6, но решили перейти на RAID 5 по причине не частых отказов SSD-дисков на серверах.

Пока что, какой-то острой нехватки IO мы не ощутили.

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