Nós, Arestas, Direções
Uma Requisição como uma Caminhada em um Grafo
Cada componente que uma requisição toca é um nó: cliente, resolver DNS, borda do CDN, proxy reverso, réplica de backend, banco de dados, cache.
Cada conexão entre dois nós é uma aresta direcionada: as requisições fluem para frente, as respostas fluem para trás. A aresta para frente representa uma conexão TCP aberta mais o protocolo sobre ela.
Uma única requisição é um caminho através deste grafo. O trabalho total que o sistema realiza para responder à requisição é igual à soma do trabalho em cada nó, mais a latência de cada aresta.
Por que se importar? Uma vez que você desenha o grafo, propriedades saltam aos olhos que são invisíveis no código:
- Contagem de saltos (hop count): o número de arestas no caminho. Cada salto adiciona latência (ida e volta de rede + processamento do nó). Menos saltos = menor limite inferior de latência.
- Grau de entrada (in-degree): quantas arestas apontam PARA UM nó. Alto grau de entrada significa que o nó recebe requisições de muitas fontes e deve escalar ou se proteger.
- Grau de saída (out-degree): quantas arestas apontam PARA FORA de um nó. Alto grau de saída significa que o nó depende de muitos downstreams e tem muitas formas de falhar.
- Vértice de corte (cut vertex): um único nó cuja remoção desconecta o grafo. Um proxy reverso sem par é um vértice de corte; removê-lo remove todo o acesso às suas origens.
Onde o Tráfego se Concentra
Fan-In = Concentração
Grau de entrada de um nó = número de arestas apontando para ele. Em um grafo de requisições, grau de entrada = número de fontes upstream que enviam requisições.
Padrão Fan-in: muitos clientes -> um CDN; muitas bordas do CDN -> poucos proxies de origem; muitos proxies -> menos réplicas de backend; muitos backends -> um único banco de dados.
A concentração é importante porque o nó com o maior grau de entrada vê a maior carga agregada. O banco de dados no final da cadeia pode ver consultas de cada solicitação ativa em todo o sistema, mesmo que nenhum usuário individual gere muito tráfego.
Fan-Out = Dependência
Grau de saída de um nó = número de arestas apontando para fora dele. Alto grau de saída significa muitas dependências a jusante.
Um backend que chama um banco de dados, dois caches, três APIs externas e uma fila tem grau de saída 7. Sua probabilidade de sucesso é aproximadamente o produto da probabilidade de sucesso de cada dependência a jusante (se todas forem necessárias para uma resposta bem-sucedida).
0,999 ^ 7 ≈ 0,993: um backend com 7 dependências a jusante, cada uma com 99,9% de confiabilidade, pode alcançar apenas ~99,3% de confiabilidade por si só, mesmo sem nenhum bug próprio.
Reduza o grau de saída por: fazer cache dos resultados a jusante, tornar dependências não críticas opcionais (degradação graciosa), paralelizar o que pode ser paralelizado.
A Assimetria
Fan-in concentra a carga; fan-out multiplica o risco. Um grafo bem estruturado minimiza ambos nos nós de maior impacto.
O banco de dados (maior fan-in): faça cache agressivamente para reduzir a carga. Use réplicas de leitura para distribuir o fan-in entre múltiplos nós.
O serviço orquestrador (maior fan-out): circuit breakers por dependência, degradação graciosa, compartimentação (bulkheads).
Um Nó Inserido Compra Flexibilidade
Indireção = Adição de um Nó Intermediário
Sem um proxy, o grafo é: client -> backend. O cliente deve conhecer o endereço do backend. Mover o backend exige atualizar o cliente (via DNS ou configuração). Esta é uma ligação rígida.
Com um proxy, o grafo se torna: client -> proxy -> backend. O cliente conhece apenas o proxy. Mover o backend exige atualizar a configuração upstream do proxy, não o cliente.
A operação no grafo: inserir um nó ao longo de uma aresta existente. A nova aresta client -> proxy é estável; a nova aresta proxy -> backend agora é responsabilidade da equipe gerenciar.
Leitura geométrica: a indireção adiciona uma camada que desacopla a mudança upstream da mudança downstream. As arestas de cada camada podem ser reconfiguradas independentemente.
Custo da Indireção
Cada camada adiciona:
- Um salto de latência (a aresta do cliente para o proxy)
- Mais um vértice de corte no caminho (o próprio proxy)
- Mais um lugar onde uma configuração incorreta pode ocorrer
Os benefícios (reconfiguração, escalabilidade, proteção, terminação de TLS, distribuição de carga) geralmente superam os custos em qualquer sistema não trivial. Mas há um limite: cada camada de indireção adiciona outro salto & outro candidato a SPOF (Ponto Único de Falha).
A regra da lenda: qualquer problema pode ser resolvido adicionando uma camada de indireção (exceto o problema de ter muitas camadas de indireção).
Ler uma Arquitetura como um Grafo
Síntese
Agora você pode ler uma arquitetura de sistema como um grafo: contar saltos, identificar vértices de corte, medir a concentração de fan-in, calcular os limites de disponibilidade a partir do fan-out e avaliar os compromissos de indireção.
Aplique os quatro.
Um novo serviço tem esta arquitetura: clients -> CDN -> reverse proxy (2 réplicas) -> backend tier (8 réplicas) -> { DB primário, cluster de cache (3 nós), API externa }.
Notas Complementares
Notas Complementares
Esta lição de geometria reformula a lição principal Proxies & Origins como uma análise de grafo direcionado.
O próximo complemento deste curso, geometry_of_stateless_horizontal_scaling, pega a matemática de réplicas da lição principal de escalonamento e deriva a curva de filas, a Lei de Little e o joelho de 80% de utilização geometricamente.
Muito bem.