trilha

System Design/05 - Reliability Patterns/Resiliency2 min

Bulkhead

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Isolar recursos em compartimentos, para que a falha de um não afunde o sistema inteiro. O nome vem das antéparas de um navio: um compartimento inundado não alaga os demais.

sem bulkhead:  [ pool único de 100 conexões ]
               serviço A lento → consome as 100 → B e C morrem

com bulkhead:  [ A: 40 ] [ B: 40 ] [ C: 20 ]
               A lento → consome só as 40 dele

Onde aplicar

Nível Compartimento
Pool de conexões Por dependência
Pool de threads Por tipo de operação
Semáforo Limite de concorrência por dependência
Instâncias Separar crítico de não-crítico
Clientes Deployment Stamps

Trade-offs

O ganho é conter o dano: uma dependência lenta deixa de derrubar tudo. É a defesa estrutural contra Noisy Neighbor e contra a exaustão de pool descrita em Busy Frontend.

O custo é eficiência. Recursos compartimentados ficam ociosos enquanto outro compartimento sofre: com 40 conexões reservadas para A e A ocioso, B não pode usá-las mesmo precisando. Isolamento garante o mínimo e sacrifica o pico.

Isso torna o dimensionamento delicado: compartimentos pequenos demais viram gargalo em uso legítimo; grandes demais não isolam nada. E dividir um pool de 100 em dez de dez costuma ser pior que não dividir.

A implementação por semáforo é a mais leve — limita concorrência sem threads dedicadas — e não isola tempo de CPU. A implementação por pool de threads isola de verdade e custa memória por thread.

Bulkhead combina com Circuit Breaker de forma complementar: o bulkhead limita quanto uma dependência pode consumir; o breaker decide quando parar de tentar. Um contém, o outro interrompe.

Exemplo prático

Uma API que depende de três serviços: pagamento (crítico), recomendação e analytics (ambos opcionais).

Com pool único de 100 conexões, analytics fica lento e consome todas — e o pagamento para de funcionar por causa de um serviço que não importa.

Com bulkhead:

pagamento:    60 conexões, timeout 3 s
recomendacao: 25 conexões, timeout 1 s, fallback em cache
analytics:    15 conexões, timeout 500 ms, fire-and-forget

Analytics lento consome no máximo suas 15 conexões. Pagamento continua com as 60 dele. A alocação reflete a criticidade — e é essa decisão explícita que o padrão exige e entrega.

Relacionado


Parte de Resiliency · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas