Обновить
8
0
Григорий Тарасенко@gle4er

Пользователь

Отправить сообщение

Как обычно, какую задачу решаем?

Чтобы лидер меньше зависел от состояния реплик.

По сути, вот это:

Хотим чтобы реплика могла догнать после существенного отставания репликации?
гарантированно?

Но чтобы еще лидер от этого не помер. Опять же: либо из-за забитого места WAL-ами, либо из-за переутилизации сети. Соответственно, слот репликации без ограничения - сразу нет, wal_keep_size имеет недостатки (которые описаны в статье):

Но у этого метода есть минусы: 

  • Лидер временно может хранить WAL-ов больше, чем указано в параметре wal_keep_size (например, из-за долгой транзакции), которые позже будут удалены. Нет гарантий, что удаленные WAL-ы будут доставлены до реплик;

  • wal_keep_size вынуждает лидера хранить ненужные WAL-ы, которые применены на репликах и просто занимают место.

Но, идея с max_slot_wal_keep_size валидна: нивелируется второй недостаток (вынужденно хранить ненужные WAL-ы), но имеет первый недостаток (который можно попробовать нивелировать "архивной репликацией" кстати).

Поэтому, по сути, "архивная репликация" работает, как вы и написали:

раз всё равно пишем архив WAL, - то можно и задействовать
restore_command чтобы из него подтягивать недостающие WAL для отстающих
реплик, попутно.

По поводу этого:

Поэтому если у вас архив wal не очень быстрый на чтение - то restore_command будет замедлять все рестарты баз

Тоже валидное замечание, спасибо, что отметили. Поэтому, в статье отмечено:

и мы имеем относительно быстрое хранилище, куда складируются WAL-ы, то
нам ничего не мешает отказаться от слотов репликации полностью.

Но да, не отмечено: что такое "относительно быстрое хранилище", поэтому, тут могут быть споры. Я понимаю, что если тащить WAL-ы из той же Москвы в Новосибирск, то идея с архивной репликацией быстро умрет :)

А по поводу поведения restore_command : спасибо, не знал. Век живи - век учись... :)

И спасибо за ценный развернутый комментарий!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Информация

В рейтинге
Не участвует
Откуда
Новосибирск, Новосибирская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Системный инженер, Администратор баз данных
Средний
Linux
PostgreSQL
Golang
Python
Docker