Ceph Failure Domains: Por que Rack-Aware não é suficiente (e o custo da paranóia)

      19 de dezembro de 2025 Eduardo Nogueira 10 min de leitura
      Ceph Failure Domains: Por que Rack-Aware não é suficiente (e o custo da paranóia)

      A redundância de rack no Ceph falha quando dependências invisíveis (PDU, Switch, Ar-condicionado) são compartilhadas. Aprenda a mapear riscos reais no CRUSH map.

      Compartilhar:

      O silêncio em um datacenter é o som mais alto que existe.

      Na minha experiência investigando "mortes súbitas" de clusters de armazenamento, a cena do crime raramente aponta para o software em si. O Ceph é resiliente; ele é projetado para assumir que o hardware vai falhar. O problema surge quando a realidade física trai a configuração lógica.

      Você configurou o failure_domain = rack. Você dorme tranquilo, acreditando que se o Rack A pegar fogo, o Rack B e C segurarão a carga. Mas quando o incidente acontece, o cluster trava em read-only ou, pior, corrompe dados por falta de quórum. A autópsia revela o culpado: Shared Fate (Destino Compartilhado). Seus racks eram distintos no CRUSH map, mas compartilhavam o mesmo disjuntor, a mesma régua de PDU ou o mesmo switch de agregação (Spine).

      Este artigo é uma investigação forense sobre como alinhar a topologia lógica do Ceph com a implacável realidade da infraestrutura física.

      O Domínio de Falha no Ceph é a unidade atômica de isolamento de risco definida no algoritmo CRUSH. Ele determina a fronteira física máxima que um incidente único pode derrubar sem afetar a disponibilidade dos dados, garantindo que as réplicas de um objeto nunca residam em dispositivos que compartilham o mesmo ponto único de falha (SPOF), como energia, refrigeração ou rede.


      A Ilusão da Segurança Física e o "Rack-Aware" no Ceph

      A configuração padrão de muitos administradores é definir o domínio de falha no nível do host ou do rack. É o "best practice" de manual. O problema é que manuais ignoram a arquitetura elétrica do seu prédio.

      O conceito de Shared Fate dita que se dois componentes dependem de um terceiro recurso upstream, eles são, para fins de disponibilidade, a mesma entidade.

      Imagine o seguinte cenário que presenciei em uma auditoria pós-incidente:

      1. O administrador configurou 3 Racks no Ceph.

      2. Regra CRUSH: 3 réplicas, uma por rack.

      3. A Realidade: O Rack 1 e o Rack 2 eram alimentados pela mesma UPS A. O Rack 3 estava na UPS B.

      4. O Evento: Falha na UPS A.

      5. O Resultado: 66% das OSDs caíram instantaneamente. O cluster perdeu o quórum (min_size não atendido). IO Blocked.

      O CRUSH map é um mapa lógico. Ele não tem sensores. Se você diz a ele que o Rack A e o Rack B são independentes, ele acredita. Ele colocará a Réplica 1 no Rack A e a Réplica 2 no Rack B. Quando a energia cai, você perde duas cópias do mesmo dado simultaneamente.

      Mapa Lógico vs. Realidade Física: O CRUSH map só protege contra o que ele conhece. Dependências ocultas (switch de agregação, disjuntores) criam domínios de falha compartilhados. Figura: Mapa Lógico vs. Realidade Física: O CRUSH map só protege contra o que ele conhece. Dependências ocultas (switch de agregação, disjuntores) criam domínios de falha compartilhados.

      A imagem acima ilustra exatamente essa desconexão. O mapa lógico oferece uma falsa sensação de segurança, enquanto a dependência oculta (o switch de agregação ou a PDU) cria um domínio de falha único e massivo.


      Anatomia do CRUSH Map: Entendendo Buckets além do padrão

      Para evitar esse cenário, precisamos dissecar como o Ceph entende a localização. O algoritmo CRUSH (Controlled Replication Under Scalable Hashing) não grava dados em discos; ele grava em Buckets.

      Um bucket é simplesmente um contêiner lógico. A hierarquia padrão geralmente é: OSDHostChassisRackRowPDUPodRoomDatacenterRegionRoot.

      O erro comum é parar no Rack. Para um investigador forense, o mapa padrão é insuficiente. Você precisa mapear a infraestrutura de suporte.

      O Mapa não é o Território

      Seus buckets devem refletir os pontos de estrangulamento, não apenas a posição do metal no chão. Se três racks compartilham um switch Spine, o seu domínio de falha real é o Spine, não o Rack.

      Se você não modelar isso, o Ceph continuará distribuindo réplicas entre racks que morrerão juntos.


      Os Domínios Invisíveis: Energia, Rede e Refrigeração

      Ao desenhar sua topologia, você deve auditar três camadas invisíveis. Se você não consegue responder "sim" para a independência dessas camadas entre seus domínios, você tem um problema de Shared Fate.

      1. O Domínio de Energia (A Causa Raiz #1)

      A energia é binária. Ou tem, ou não tem.

      • PDU/Circuito: Racks vizinhos frequentemente compartilham circuitos.

      • UPS: Em datacenters menores, uma única UPS pode segurar metade da sala.

      • Gerador: Se todo o seu cluster depende de um único gerador sem redundância N+1 real, seu domínio de falha é "o prédio".

      2. O Domínio de Rede (Spine/Leaf)

      Topologias Spine-Leaf são ótimas para largura de banda, mas perigosas se mal mapeadas.

      • Se o Rack A e B estão em switches ToR (Leaf) diferentes, mas ambos sobem para o mesmo par de Spines, e esse par de Spines falha (bug de firmware, erro de config), ambos os racks somem.

      3. O Domínio Térmico (Refrigeração)

      Raramente considerado, mas letal. Em corredores confinados, a falha de uma unidade CRAC (Computer Room Air Conditioning) pode elevar a temperatura de uma fileira (Row) inteira a níveis de desligamento térmico em minutos.


      Configurando Custom Buckets no Ceph: Do conceito à CLI

      Não aceite a hierarquia padrão. Se a sua restrição principal é a energia, crie um bucket chamado power-circuit. Se é o switch, crie switch-group.

      Vamos operar. Suponha que temos 4 racks, mas eles estão divididos em 2 circuitos de energia (A e B). Queremos garantir que nenhuma réplica seja duplicada dentro do mesmo circuito.

      Passo 1: Criar o novo tipo de bucket

      Primeiro, precisamos dizer ao CRUSH que existe algo chamado "circuit". O comando padrão não traz isso. Na verdade, podemos usar tipos existentes ou criar novos se o mapa permitir, mas frequentemente reutilizamos row ou room se a semântica encaixar. Vamos ser puristas e adicionar um tipo se necessário, ou usar a hierarquia lógica.

      Vamos assumir que vamos agrupar racks em "Rows" que representam nossos circuitos elétricos.

      Passo 2: Mover os Racks para os Circuitos (Rows)

      A estrutura atual é Root -> Rack -> Host. A nova estrutura será Root -> Row (Circuito) -> Rack -> Host.

      ceph osd crush add-bucket circuito-A row
      ceph osd crush add-bucket circuito-B row
      
      # 2. Mova os buckets para a raiz (default)
      ceph osd crush move circuito-A root=default
      ceph osd crush move circuito-B root=default
      
      # 3. Mova os Racks existentes para dentro dos circuitos corretos
      # Supondo que rack1 e rack2 estão na energia A
      ceph osd crush move rack1 row=circuito-A
      ceph osd crush move rack2 row=circuito-A
      
      # Supondo que rack3 e rack4 estão na energia B
      ceph osd crush move rack3 row=circuito-B
      ceph osd crush move rack4 row=circuito-B
      

      Passo 3: Criar a Regra CRUSH

      Agora, o passo crítico. Você precisa de uma regra que escolha o row (circuito) como o primeiro passo da separação, não o rack.

      # Criar uma regra para pool replicado que isola no nível de ROW (nosso circuito)
      ceph osd crush rule create-replicated regra-energia default row host
      

      Tradução do comando: "Crie uma regra chamada regra-energia, começando na raiz default, escolha buckets do tipo row para isolar falhas, e dentro deles, escolha host para alocar as OSDs (leafs)."

      Agora, se o circuito-A cair (levando rack1 e rack2), o Ceph garante que as réplicas 2 e 3 estarão seguras no circuito-B.


      O Trade-off de Latência: Quando a distância mata a performance

      Aqui entra o "Custo da Paranóia". Quanto mais seguro você quer estar, mais longe você afasta seus domínios de falha. E a distância é inimiga da latência de gravação.

      O Ceph é fortemente consistente. Uma gravação (write) só é confirmada ao cliente (ack) quando todas as réplicas ativas confirmaram a gravação no journal/WAL.

      Se você define seu domínio de falha como "Datacenter" (para sobreviver a um incêndio) e seus DCs estão a 5ms de distância (ida e volta - RTT):

      1. Cliente envia Write.

      2. Primary OSD grava.

      3. Primary envia para Secondary OSD (outro DC, +5ms).

      4. Secondary grava e confirma (+5ms).

      5. Primary confirma ao cliente.

      Sua latência de disco NVMe de 0.05ms agora é irrelevante. Sua latência de gravação é determinada pela velocidade da luz na fibra ótica.

      O Custo da Distância: Quanto maior o domínio de falha, maior a latência de gravação. A física é implacável. Figura: O Custo da Distância: Quanto maior o domínio de falha, maior a latência de gravação. A física é implacável.

      Tabela de Impacto: Segurança vs. Latência

      Nível do Domínio de Falha Risco Mitigado Custo de Latência (Network RTT) Custo de Infraestrutura
      OSD / Host Falha de Disco/Servidor Baixo (< 0.1ms intra-rack) Baixo (Switch ToR)
      Rack Falha de ToR Switch / Cabo Médio (< 0.2ms inter-rack) Médio (Spine/Core)
      Row / PDU Disjuntor / PDU de fileira Médio (< 0.3ms) Alto (Redundância elétrica)
      Room / Datacenter Incêndio / Falha Geral de Energia Crítico (1ms - 10ms+) Muito Alto (Dark Fiber/DWDM)

      O Veredito Forense: Não escale seu domínio de falha para "Datacenter" a menos que sua aplicação suporte a latência ou você esteja usando replicação assíncrona (RBD Mirroring), que é outra conversa. Para clusters síncronos, o limite saudável geralmente é "Sala" ou "Zona de Fogo" dentro do mesmo campus.


      Validação Forense: Como simular e medir o impacto

      Não espere o desastre para testar sua teoria. Você deve validar se o CRUSH map está realmente distribuindo os dados como você planejou.

      1. Verificação Estática (Dry-Run)

      Use o peering simulado para ver onde o Ceph colocaria os dados.

      # Teste onde o CRUSH colocaria um grupo de placement (PG) usando a regra criada
      ceph osd crush rule create-replicated teste_regra default row
      ceph osd test-crush-rule --rule=teste_regra --num-rep=3 --show-mappings
      

      A saída deve mostrar conjuntos de OSDs como [12, 45, 89]. Verifique manualmente: A OSD 12 está no Circuito A? A 45 está no Circuito B? Se todas as 3 estiverem no Circuito A, sua regra falhou.

      2. O Teste de "Scream" (Cuidado: Produção)

      Se você tem um ambiente de staging, a única validação real é física.

      1. Inicie uma carga de trabalho de escrita (ex: fio).

      2. Desligue fisicamente o switch de agregação de um domínio (ou o disjuntor de um rack).

      3. Observe o ceph -w.

      O que deve acontecer:

      • O cluster entra em estado degraded (pois perdeu réplicas).

      • O I/O NÃO deve pausar (blocked).

      • Se o I/O pausar, significa que alguns PGs tinham todas as suas réplicas ou a maioria delas (quorum) dentro do domínio que falhou.

      Checklist de Investigação de Falhas

      • Os domínios definidos no CRUSH correspondem à fiação elétrica real?

      • Existe algum switch central que conecta todos os domínios definidos?

      • A latência de rede entre os domínios mais distantes suporta o SLA de escrita?

      A paranóia custa dinheiro e latência, mas a ignorância custa seus dados. Escolha seu veneno com sabedoria.


      Referências & Leitura Complementar

      • Ceph Documentation: CRUSH Maps - The definitive guide on editing the map.

      • Weil, S. A., et al. (2006): "CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data" - O paper original que explica a matemática dos buckets.

      • RFC 7938: Use of BGP for Routing in Large-Scale Data Centers - Entendendo topologias Spine-Leaf e domínios de falha de rede.

      • Gregg, Brendan: Systems Performance: Enterprise and the Cloud - Para metodologias de medição de latência.

      #Ceph CRUSH Map #Failure Domains #Alta Disponibilidade Storage #Ceph Rack Awareness #Arquitetura de Storage
      Eduardo Nogueira

      Eduardo Nogueira

      Gerente de Recuperação de Desastres

      Seus dados não estão seguros até que ele diga que estão. Especialista em estratégias de backup imutável e RPO/RTO.