Skip to content

Redundância

A autonomia do streamer cobre o ar: uma queda do central não toca o espectador, os streams seguem transmitindo e gravando por conta própria. A redundância cobre a outra metade — a gestão: para que um tempo de queda do central não se estenda pelo tempo que alguém leve para levantar a máquina à mão.

Esta página trata de que componentes formam uma instalação com reserva, quantas instâncias de cada um levantar e o que exatamente a segunda muda. Como implantá-la — Um grupo do central em servidores separados; como ver com os próprios olhos — o laboratório no Docker. O mapa de estado e garantias — Componentes e confiabilidade.

O que é tornado redundante e o que não

Só o plano de controle precisa de reserva. O caminho da mídia já não depende dele: o streamer captura a fonte, transcodifica, grava o arquivo e serve o stream sozinho, e um espectador a quem foi dada uma URL pública de entrega não passa pelo central de forma alguma.

Daí a regra com que começa qualquer instalação com reserva: o central e a transmissão vivem em máquinas diferentes. O streamer local dentro do processo do central não serve para uma instalação assim — ele compartilha a sorte do processo, e seus streams caem junto com a gestão.

O mandato: qual instância faz o trabalho

Várias instâncias do central sobre um mesmo banco formam um grupo. Parte do trabalho é inofensivo fazer em todas ao mesmo tempo, e parte não: dois layouters decidindo ao mesmo tempo começariam a mover streams entre máquinas sem motivo.

Esse trabalho é feito por uma única instância do grupo — a que tomou o mandato correspondente. Três propriedades do mandato determinam todo o comportamento do grupo diante de uma falha.

  • O mandato é emitido pelo PostgreSQL, não pela configuração. Na configuração de uma instância há apenas um papel declarado — «esta máquina está pronta para fazer este trabalho». É preciso declará-lo em todas, ou não haverá quem assuma o trabalho.
  • O mandato se libera sozinho, com a morte do processo. Ele vive numa conexão própria com o banco: se a sessão morre, o mandato fica livre e um vizinho vem buscá-lo por conta própria. Sem timeouts, sem analisar executores travados, sem confirmação manual.
  • Cada emissão leva um número: a época. Ela cresce a cada troca de titular e viaja com cada escrita. Uma instância que acorda de uma pausa já sem ser a titular recebe uma recusa na escrita, em vez de estragar a alocação depois do fato.

Os mandatos são vários e são independentes. O central não tem um líder único: a alocação e a imagem do «agora mesmo» podem estar em máquinas diferentes, e isso é um estado normal.

Quem tem o quê se vê no console: Cluster → Central.

Componentes e sua quantidade

O central não é um processo com um papel, mas vários trabalhos distintos, e eles são tornados redundantes de maneiras distintas.

Componente Quantos executores O que a segunda instância traz
PostgreSQL Um cluster Tornado redundante pelo próprio banco, não pelo Catena
Manipuladores de requisições Todas as instâncias A gestão sobrevive à perda de uma máquina
Imagem do estado atual O titular do mandato stats Um titular de reposição em segundos; a imagem é refeita
Layouter O titular do mandato layouter Um executor de reposição sem intervenção do operador
Migrações do esquema Exatamente uma instância Nada: dois migradores são uma corrida, ver abaixo
Coleta de sessões Um executor por streamer Os streamers da instância caída passam a uma viva
Trabalhos periódicos Em todas Nada: de todo modo apenas uma faz o serviço
Ponto de entrada do operador Um endereço
Streamers Quantos o ar exigir A redundância deles vem da alocação, não daqui

A seguir, o que cada um faz e por que a quantidade é essa.

Manipuladores de requisições

É o que o operador e o cluster enxergam como central: o console, a API de gestão, o frontal do reprodutor, a exportação de métricas e a recepção da sincronização dos streamers. Um manipulador não guarda estado próprio — tudo está no PostgreSQL —, então pode haver quantas instâncias se queira, e à requisição do operador responde qualquer uma.

Um streamer, porém, não precisa de um balanceador que o espalhe pelo grupo, e sim de uma lista de endereços: ele fica no endereço que responde e passa ao seguinte após uma requisição malsucedida. A lista é definida na configuração do streamer e não se amplia sozinha — ao acrescentar uma terceira instância, escreva o endereço dela nos streamers.

A segunda instância traz duas coisas:

  • A gestão sobrevive à perda de uma máquina. O operador e os streamers se mudam para uma instância viva.
  • Atualização sem janela de parada. As instâncias são atualizadas por vez — ver Atualização.

Imagem do estado atual

O que o console mostra sobre o «agora mesmo» — quais streams estão rodando, quem os assiste, quantos espectadores — o central não lê do banco. No banco está o que deve ser (ajustes, alocação) e o que já aconteceu (sessões fechadas, registros), enquanto o «agora mesmo» vive na memória.

A imagem é uma só para todo o grupo, e quem a mantém é o titular do mandato stats. As demais instâncias chegam a ela pela rede, no endereço que o titular anunciou de si. Por isso todo o parque é visível a partir de qualquer endereço do grupo, embora os streamers reportem a instâncias diferentes.

Daí a única coisa que o operador precisa saber sobre uma troca de titular: a imagem não se muda, ela é refeita — a partir das sincronizações seguintes, em segundos. Nessa janela o console mostra honestamente números incompletos: um stream já transmite mas ainda não apareceu na lista dos ativos.

Não há nada a perder no processo — nem o arquivo, nem a contabilidade de sessões, nem os ajustes: apenas a imagem do «agora mesmo» está incompleta. A regra prática: o primeiro meio minuto após uma troca de titular não é prova do estado do cluster, e um alarme por «streams sumidos» nessa janela significa aquecimento, não avaria.

Layouter

O layouter decide qual stream roda em qual máquina. Duplicar esse trabalho é nocivo: dois layouters sobre um mesmo banco decidiriam ao mesmo tempo e escreveriam no registro de alocação em disputa — os streams começariam a se mudar entre máquinas sem motivo.

Por isso as passagens são executadas pelo titular do mandato layouter, e suas escritas vão protegidas pela época de emissão. O papel layouter, por sua vez, é declarado por todas as instâncias do grupo: declará-lo em apenas uma é ficar sem alocação quando morrer justamente essa máquina.

Uma instância que não tem o mandato está completa em todo o resto: serve o console, a API e a sincronização dos streamers. Não é preciso ativar nada durante uma avaria — o mandato se muda sozinho.

Migrações do esquema

O único trabalho que nenhum mandato vigia é aplicar as migrações na partida. Dois processos que partam ao mesmo tempo vão lançá-las em disputa, então o papel migrate é declarado por exatamente uma instância e as demais partem depois dela.

A ressalva importa mais do que parece: uma lista de papéis vazia não significa «nenhum papel», e sim todos, migrate incluído. Uma segunda instância levantada com uma cópia da configuração da primeira acaba sendo um segundo migrador.

Coleta de sessões dos streamers

Quem assistiu o quê — as sessões — o central não recebe passivamente: ele mesmo as puxa dos streamers, por um canal contínuo até cada streamer.

O trabalho é dividido por streamer: o canal de um streamer é puxado por um único executor a cada momento, e streamers diferentes podem ser puxados por executores diferentes. Por isso a perda de uma instância não custa uma parada da contabilidade, e sim a mudança de seus streamers para uma viva.

Um tempo de queda também não perde registros: o streamer guarda seu registro de sessões por vários dias, e a coleta continua de onde parou. Uma hora de queda significa que os registros chegarão mais tarde, não que não vão chegar.

Trabalhos periódicos

O resto do trabalho de fundo roda por horário: a carga do guia de programação, a limpeza de registros pela retenção, a contabilidade dos armazenamentos VOD (aposentar os das máquinas sumidas, expirar os envios inacabados), retirar o status dos streamers que se calaram.

Eles giram em todas as instâncias, e isso é seguro — mas por duas razões diferentes.

  • A carga do guia de programação divide suas fontes com uma trava no banco: antes de uma passagem a instância toma a trava da fonte e, se um vizinho já a está atualizando, a passagem é pulada.
  • As limpezas e a contabilidade de armazenamentos não precisam de trava: repeti-las não muda nada — não há o que apagar do que já foi apagado.

Não é preciso distribuir esses trabalhos entre instâncias à mão, nem desativá-los em nenhuma.

PostgreSQL

O banco é o único depósito de estado e o único ponto cuja redundância o Catena não assume. É preciso um cluster lógico acessível por todas as instâncias num mesmo endereço; a tolerância a falhas dele é tarefa do próprio banco: uma réplica com comutação ou uma instância gerenciada de um provedor.

Dois servidores de banco independentes não são redundância, e sim duas instalações distintas: a alocação e o registro de streamers vão divergir.

Backups continuam necessários: a reserva protege da perda de uma máquina, não de uma exclusão por engano — ver Backup e restauração.

Ponto de entrada do operador

O operador precisa de um único endereço que encontre sozinho uma instância viva: um nome DNS com comutação ou um balanceador diante do grupo.

Os streamers não passam por ele — eles têm sua própria lista de endereços, e um intermediário a mais no caminho da sincronização só acrescenta um ponto de falha.

Streamers

Os streamers não são tornados redundantes pela quantidade de instâncias de gestão, e sim pela alocação: um stream a que foram dadas mais de uma máquina sobrevive à perda de qualquer uma delas. É um tema separado do central — ver A lista de streamers.

Cenários

Uma instância falha

Tudo acontece sozinho, sem intervenção.

  • Os streamers passam ao endereço seguinte da sua lista após uma requisição malsucedida. Não precisam ser reconfigurados, e não há corte na transmissão.
  • Os mandatos da instância perdida se mudam para uma viva em segundos. A alocação segue funcionando, os streams novos são alocados como sempre.
  • A imagem do «agora mesmo» é refeita. Por meio minuto os números do console ficam incompletos: é aquecimento, não sumiço.
  • O operador trabalha pelo mesmo endereço e com a mesma senha. O estado vive no banco, não na máquina perdida: o registro de streamers, os ajustes e a alocação continuam lá.

A única coisa que uma avaria toca de verdade é a aplicação das migrações: se a instância com o papel migrate foi a que morreu, outra precisa assumi-lo enquanto durar a recuperação, ou a próxima atualização não terá por onde começar.

Uma instância volta

Voltar não é uma operação de emergência e não exige janela de parada. Nada se muda de volta no processo, e isso é uma decisão, não um descuido.

  • Os mandatos ficam com quem os tem. Não há nada a ganhar tirando-os: o titular está trabalhando, e uma troca de titular custa outro aquecimento da imagem.
  • O streamer fica no endereço para o qual foi. Enquanto esse endereço responder, não há nada a ganhar trocando-o.

O grupo funciona em qualquer arranjo, então não é preciso devolvê-lo ao original.

Atualização planejada

As instâncias são atualizadas por vez, e é o mesmo cenário, só que controlado: enquanto uma é atualizada, os streamers trabalham com a outra. Os mandatos se mudam duas vezes no processo — uma por reinício — e das duas vezes sozinhos. A ordem e as verificações — Atualização.

Perda do banco de dados

A gestão para por completo: pode haver quantas instâncias se queira, mas o estado entre todas é um só. Enquanto o banco estiver indisponível, o console e a API não servem requisições, e streams novos não são criados nem alocados. Nesse tempo ninguém tem mandato algum — é o banco que os emite.

O ar, por sua vez, continua: os streamers são autônomos — transmitem, gravam o arquivo e o servem ao espectador sem perguntar ao central. Por isso a perda do banco é um tempo de queda da gestão, não do ar.

A recuperação fica a cargo do próprio banco (comutação para uma réplica) ou de um backup; ver Backup e restauração.