Pull to refresh
8
Григорий Тарасенко@gle4er

User

2
Subscribers
Send message

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

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

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

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

Но чтобы еще лидер от этого не помер. Опять же: либо из-за забитого места 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. Плюс используется асинхронная потоковая репликация, поэтому некоторые данные до реплик могут не доехать, особенно если лидер будет перегружен.

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity

Specialization

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