Skip to content

Резервирование

Автономия стримера закрывает эфир: падение central зрителя не касается, стримы вещают и пишут архив сами. Резервирование закрывает второе — управление: чтобы простой central не растягивался на время, пока машину поднимают руками.

Эта страница — про то, из чего состоит инсталляция с резервом, сколько инстансов каждого компонента запускать и что именно меняет второй. Как это развернуть — Группа central на нескольких серверах; как посмотреть своими глазами — практикум в Docker. Карта состояния и гарантий — Компоненты и надёжность.

Что резервируется, а что нет

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

Отсюда правило, с которого начинается любая инсталляция с резервом: central и вещание живут на разных машинах. Локальный стример внутри процесса central для такой инсталляции не годится — он разделяет судьбу процесса, и его стримы падают вместе с управлением.

Мандат: кто из инстансов делает работу

Несколько инстансов central над одной базой — это группа. Часть работы в ней безвредно делать всем сразу, а часть — нет: два лейаутера, решающих одновременно, начнут гонять стримы между машинами без причины.

Такую работу в группе делает один инстанс — тот, который взял на неё мандат. Три свойства мандата определяют всё поведение группы при отказе.

  • Мандат выдаёт PostgreSQL, а не конфиг. В конфиге инстанса стоит только притязание — «эта машина готова делать такую работу». Заявлять его нужно у всех, иначе некому будет подхватить.
  • Мандат освобождается смертью процесса сам. Он живёт на отдельном соединении с базой: сессия умерла — мандат свободен, и сосед приходит за ним сам. Ни таймаутов, ни разбора зависших исполнителей, ни ручного подтверждения.
  • У каждой выдачи есть номер — эпоха. Она растёт при смене держателя и едет вместе с каждой записью. Инстанс, очнувшийся после паузы уже не держателем, получает отказ на записи, а не портит размещение задним числом.

Мандатов несколько, и они независимы. Единого лидера у central нет: размещение и картину «прямо сейчас» могут держать разные машины, и это штатное состояние.

Кто что держит, видно в консоли: Кластер → Central.

Компоненты и их количество

Central — не один процесс с одной ролью, а несколько разных работ, и резервируются они по-разному.

Компонент Сколько исполнителей Что даёт второй инстанс
PostgreSQL Один кластер Резервируется средствами самой базы, не Catena
Обработчики запросов Все инстансы Управление переживает потерю машины
Картина текущего состояния Держатель мандата stats Замену держателя за секунды; картина набирается заново
Лейаутер Держатель мандата layouter Замену исполнителя без вмешательства оператора
Миграции схемы Ровно один инстанс Ничего: два мигратора — гонка, см. ниже
Забор сессий со стримеров По исполнителю на стример Стримеры упавшего инстанса переходят к живому
Периодические работы Во всех Ничего: дело всё равно делает кто-то один
Точка входа оператора Один адрес
Стримеры Сколько требует эфир Резервируются не здесь, а размещением

Дальше — что каждый из них делает и почему количество именно такое.

Обработчики запросов

Это то, что оператор и кластер видят как central: консоль, management API, плеерный фронт, выдача метрик и приём синхронизации от стримеров. Состояния у обработчика своего нет — всё лежит в PostgreSQL, — поэтому инстансов может быть сколько угодно, и на запрос оператора отвечает любой.

Стримеру, однако, нужен не балансировщик, размазывающий его по группе, а список адресов: он держится того адреса, который отвечает, и переходит к следующему после неудавшегося запроса. Список задаётся в конфиге стримера и сам собой не пополняется — добавив третий инстанс, впишите его адрес стримерам.

Второй инстанс даёт две вещи:

  • Управление переживает потерю машины. Оператор и стримеры переходят на живой инстанс.
  • Обновление без окна простоя. Инстансы обновляются по очереди — см. Обновление.

Картина текущего состояния

То, что консоль показывает про «прямо сейчас» — какие стримы идут, кто их смотрит, сколько зрителей, — central не читает из базы. В базе лежит то, что должно быть (настройки, размещение) и что уже случилось (закрытые сессии, журналы), а «прямо сейчас» живёт в памяти.

Картина одна на всю группу, и держит её обладатель мандата stats. Остальные инстансы ходят к ней по сети — по адресу, который держатель объявил о себе. Поэтому весь парк виден с любого адреса группы, хотя стримеры отчитываются в разные инстансы.

Отсюда единственное, что оператору нужно знать про смену держателя: картина не переносится, а набирается заново — из ближайших синхронизаций, за секунды. В это окно консоль честно показывает неполные цифры: стрим уже вещает, но в списке активных ещё не появился.

Потерять при этом нечего — ни архив, ни учёт сессий, ни настройки: неполна только картинка «прямо сейчас». Практическое правило: первые полминуты после смены держателя — не показание о состоянии кластера, и тревога о «пропавших стримах» в этом окне означает прогрев, а не аварию.

Лейаутер

Лейаутер решает, какой стрим на какой машине идёт. Дубль этой работы вреден: два лейаутера над одной базой принимали бы решения одновременно и писали в журнал размещения наперегонки — стримы переносились бы между машинами без причины.

Поэтому прогоны исполняет держатель мандата layouter, а его записи ограждены эпохой выдачи. Роль layouter при этом заявляют все инстансы группы: заявить её у одного значит остаться без размещения, когда именно эта машина умрёт.

Инстанс, не держащий мандата, полноценен во всём остальном: он обслуживает консоль, API и синхронизацию стримеров. Ничего включать при аварии не нужно — мандат переходит сам.

Миграции схемы

Единственная работа, которую мандат не сторожит, — накат миграций при старте. Два процесса, стартовавшие одновременно, погонят их наперегонки, поэтому роль migrate заявляет ровно один инстанс, а остальные стартуют после него.

Оговорка важнее, чем кажется: пустой список ролей означает не «никаких ролей», а все, включая migrate. Второй инстанс, поднятый копией конфига первого, окажется вторым мигратором.

Забор сессий со стримеров

Кто и что смотрел — сессии — central не получает пассивно: он сам постоянно тянет их со стримеров, по непрерывному каналу на каждый стример.

Работа делится по стримерам: канал одного стримера в любой момент тянет один исполнитель, разные стримеры могут тянуться разными. Поэтому потеря инстанса стоит не остановки учёта, а переезда его стримеров на живой.

Простой тоже не теряет записей: стример держит журнал сессий у себя несколько суток, и забор продолжается с того места, где прервался. Часовой простой означает, что записи приедут позже, а не что их не будет.

Периодические работы

Остальное фоновое — работы по расписанию: загрузка программы передач, чистка журналов по срокам хранения, учёт хранилищ VOD (гашение хранилищ пропавших машин, истечение незавершённых загрузок), снятие статуса с замолчавших стримеров.

Они крутятся во всех инстансах, и это безопасно — но по двум разным причинам.

  • Загрузка программы передач делит источники замком в базе: перед заходом инстанс берёт замок на источник, и, если его уже обновляет сосед, заход пропускается.
  • Чисткам и учёту хранилищ замок не нужен: повторное выполнение ничего не меняет — удалять уже удалённое нечего.

Разносить эти работы по инстансам руками не нужно, выключать где-либо — тоже.

PostgreSQL

База — единственное хранилище состояния и единственная точка, резервирование которой Catena не берёт на себя. Нужен один логический кластер, доступный всем инстансам по одному адресу, а его собственная отказоустойчивость — задача самой базы: реплика с переключением или управляемый инстанс провайдера.

Два независимых сервера базы — не резервирование, а две разные инсталляции: у них разойдутся и размещение, и реестр стримеров.

Бэкап нужен по-прежнему: резерв защищает от потери машины, но не от ошибочного удаления — см. Бэкап и восстановление.

Точка входа оператора

Оператору нужен один адрес, который сам находит живой инстанс: DNS-имя с переключением или балансировщик перед группой.

Стримеры через него не ходят — у них свой список адресов, и лишний посредник на пути синхронизации только добавит точку отказа.

Стримеры

Стримеры резервируются не количеством инстансов управления, а размещением: стрим, которому задано больше одной машины, переживает потерю любой из них. Это отдельная от central тема — см. Список стримеров.

Сценарии

Отказ инстанса

Всё происходит само, без вмешательства.

  • Стримеры уходят на следующий адрес своего списка за один неудавшийся запрос. Перенастраивать их не нужно, и перерыва в вещании нет.
  • Мандаты погибшего инстанса переходят к живому за секунды. Размещение продолжает работать, новые стримы размещаются как обычно.
  • Картина «прямо сейчас» набирается заново. Полминуты цифры в консоли неполны — это прогрев, а не пропажа.
  • Оператор работает через тот же адрес и тем же паролем. Состояние лежит в базе, а не в потерянной машине: реестр стримеров, настройки, размещение — на месте.

Единственное, чего авария касается по-настоящему, — накат миграций: если погиб инстанс с ролью migrate, её на время восстановления берёт на себя другой, иначе следующее обновление не с чего будет начать.

Возврат инстанса

Возврат — не аварийная операция и окна простоя не требует. Обратного переезда при этом не происходит, и это решение, а не недоделка.

  • Мандаты остаются у того, кто их держит. Отбирать их незачем: держатель работает, а смена держателя стоит нового прогрева картины.
  • Стример остаётся на том адресе, куда ушёл. Пока адрес отвечает, менять его незачем.

Группа работает в любой расстановке, поэтому возвращать её к исходной не требуется.

Плановое обновление

Инстансы обновляют по очереди, и это тот же сценарий, только управляемый: пока обновляется один, стримеры работают со вторым. Мандаты при этом переходят дважды — по разу на каждый перезапуск, — и оба раза сами. Порядок и проверки — Обновление.

Потеря базы

Управление останавливается целиком: инстансов может быть сколько угодно, но состояние у них одно. Пока база недоступна, консоль и API не обслуживают запросы, новые стримы не заводятся и не размещаются. Мандатов в это время не держит никто — их выдаёт база.

Эфир при этом продолжается: стримеры автономны — вещают, пишут архив и отдают его зрителю, не спрашивая central. Поэтому потеря базы — это простой управления, а не эфира.

Восстановление — средствами самой базы (переключение на реплику) или из бэкапа; см. Бэкап и восстановление.