Fundamentos de Sistemas Distribuídos
Por que sistemas distribuídos (distributed systems) importam para a IA
A maioria dos sistemas modernos de IA são sistemas distribuídos (distributed systems) — não porque a distribuição esteja na moda, mas porque as cargas de trabalho de IA naturalmente excedem os limites de uma única máquina:
- Dados: Corpos de treinamento, logs, vetores de embedding (embeddings) e tabelas de atributos (feature tables) frequentemente chegam a ter de terabytes a petabytes. Você precisa de armazenamento distribuído e processamento paralelo para ingerir, limpar e versioná-los.
- Treinamento (training): Modelos de ponta (especialmente modelos grandes de Arquitetura Transformer (Transformer Architecture)) exigem múltiplas GPUs e, com frequência, múltiplas máquinas. O treinamento é fundamentalmente um problema de coordenação: mover dados, sincronizar gradientes, lidar com falhas e fazer criação de checkpoints (checkpointing) do progresso.
- Inferência em produção (production inference): Serviços reais precisam lidar com tráfego variável, orçamentos rigorosos de latência (latency) e implantações contínuas. Sistemas de serviço de modelos devem escalar horizontalmente, isolar falhas e manter observabilidade (observability).
Fundamentos de sistemas distribuídos explicam por que esses desafios existem e fornecem um kit de conceitos — replicação (replication), particionamento (sharding), consenso (consensus), tolerância a falhas (fault tolerance), consistência (consistency) — que aparecem em toda parte, de um repositório de atributos a um job de treinamento em GPU com múltiplos nós.
Este artigo foca nos fundamentos de que você precisa para raciocinar sobre sistemas distribuídos em pipelines de IA, treinamento distribuído e inferência em produção.
O que torna um sistema “distribuído”?
Um sistema distribuído é um conjunto de computadores independentes que aparece para seus usuários como um único sistema coerente. A palavra-chave é independentes: cada máquina tem seu próprio relógio, pode falhar de forma independente e se comunica por uma rede que pode atrasar, perder ou reordenar mensagens.
As restrições definidoras
Sistemas distribuídos diferem de programas em nó único por causa de:
- Falha parcial (partial failure): Um nó pode falhar enquanto outros continuam executando. Isso é o padrão, não a exceção.
- Redes não confiáveis (unreliable networks): Mensagens podem ser atrasadas, duplicadas, perdidas ou reordenadas.
- Ausência de um relógio global (global clock): Você não consegue ordenar eventos perfeitamente usando tempo de relógio de parede entre máquinas.
- Concorrência (concurrency): Muitas operações acontecem simultaneamente; condições de corrida sutis tornam-se prováveis.
- Custos de latência: Comunicação é cara quando comparada a acesso à memória ou computação local.
Um modelo mental útil é: tudo o que pode dar errado vai dar errado ocasionalmente, e você deve projetar para que “ocasionalmente” não vire “catastroficamente”.
As “falácias da computação distribuída (fallacies of distributed computing)” (edição IA)
Suposições incorretas comuns:
- A rede é confiável (não é).
- A latência é zero (ela domina muitos caminhos de inferência).
- A largura de banda é infinita (o treinamento pode ser limitado por comunicação).
- A topologia não muda (o autoescalonamento (autoscaling) muda a membresia constantemente).
- Existe um único administrador (propriedade por múltiplas equipes e serviços de nuvem complicam a operação).
- O custo de transporte é zero (mover conjuntos de dados é caro).
- A rede é segura (confiança zero (zero-trust) é cada vez mais necessária).
Blocos de construção centrais: comunicação, estado e coordenação
Sistemas distribuídos geralmente são compostos por três tipos de blocos de construção:
- Primitivas de comunicação: RPC (chamada de procedimento remoto, Remote Procedure Call) e mensageria (messaging) (filas/fluxos).
- Gestão de estado: onde os dados vivem, como são particionados e como são replicados.
- Mecanismos de coordenação: locks, eleição de líder e consenso para decisões compartilhadas.
RPC vs mensageria (messaging)
RPC se encaixa em caminhos online de requisição:
- Exemplos: gRPC/HTTP para um servidor de modelo, serviço de consulta de atributos, serviço de busca vetorial.
- Prós: modelo mental simples, baixa latência para requisição/resposta.
- Contras: fortemente acoplado; novas tentativas e tempos limite devem ser tratados com cuidado para evitar sobrecarga.
Mensageria (filas/fluxos) se encaixa em pipelines e tarefas assíncronas:
- Exemplos: Kafka/PubSub/Kinesis para logs de eventos; filas Celery/Redis para jobs.
- Prós: buffering, desacoplamento de produtores/consumidores, suavização de picos.
- Contras: exige pensar cuidadosamente sobre garantias de entrega e idempotência (idempotency).
Em sistemas de IA, você frequentemente combina os dois: inferência é RPC; logging, rotulagem e ingestão offline para treinamento são fluxos de eventos.
Tempos limite, novas tentativas e idempotência
Tempos limite e novas tentativas são essenciais — mas perigosos:
- Uma nova tentativa pode duplicar trabalho (cobrar duas vezes, gravar duas vezes, enfileirar duas vezes).
- Uma nova tentativa pode amplificar carga durante uma indisponibilidade (“tempestade de retries”).
- Um tempo limite não diz se a operação foi bem-sucedida — apenas que você não obteve resposta.
Projete operações para serem idempotentes: aplicá-las múltiplas vezes tem o mesmo efeito que aplicá-las uma vez. Isso é especialmente importante para pipelines de dados e escritas de atributos.
# Pseudocode: idempotent message processing with a deduplication key.
def handle_message(msg):
# msg.id is globally unique (or unique per producer partition)
if dedup_store.contains(msg.id):
return # already processed (safe to ignore duplicate)
# Do the side effect (write feature row, update index, etc.)
write_result = write_to_db(msg.payload)
# Only mark processed after successful write
dedup_store.put(msg.id, write_result.version)
Na prática, a deduplicação (deduplication) pode usar:
- uma restrição de unicidade no banco de dados,
- um padrão outbox/inbox transacional (transactional outbox/inbox pattern),
- ou um tópico Kafka compactado chaveado por ID da mensagem.
Como os dados são distribuídos: particionamento e replicação
Quase todo sistema de IA eventualmente enfrenta uma pergunta: onde os dados vivem?
Particionamento (sharding)
Particionamento divide um conjunto de dados entre nós para que você possa escalar capacidade e vazão (throughput).
Estratégias comuns:
- Particionamento baseado em hash: shard = hash(key) mod N
Bom balanceamento de carga, mas re-particionar é penoso quando N muda. - Hashing consistente (consistent hashing): reduz movimentação quando nós entram/saem (útil para caches e algumas lojas chave-valor).
- Particionamento por faixa: particione por intervalos de chave (por exemplo, user_id 0–1M)
Consultas por intervalo são eficientes, mas há risco de “faixas quentes”.
Exemplos específicos de IA:
- Particionar uma tabela de embeddings por ID de entidade.
- Particionar um índice vetorial por centróide/partição (comum em sistemas de vizinho mais próximo aproximado (ANN, approximate nearest neighbor)).
- Particionar dados de treinamento por faixas de arquivos/registros para carregamento paralelo.
Um problema prático é o desbalanceamento (skew): poucas chaves ou shards recebem a maior parte do tráfego (usuários celebridades, itens populares, prompts quentes). Desbalanceamento aumenta a latência de cauda (tail latency) e torna a vazão instável.
Replicação
Replicação copia dados para múltiplos nós por disponibilidade e escalabilidade de leitura.
- Líder/seguidor: um nó aceita escritas; seguidores replicam e servem leituras.
- Multi-líder: múltiplos nós aceitam escritas (maior disponibilidade, resolução de conflitos mais difícil).
- Baseado em quórum: leituras/escritas exigem concordância de um subconjunto de réplicas.
Replicação é crítica para:
- repositórios de atributos de alta disponibilidade,
- armazenamentos de metadados (versões de conjuntos de dados, execuções de treinamento),
- registros de modelos e armazenamentos de artefatos.
Replicação introduz uma troca central: consistência vs disponibilidade.
Modelos de consistência (e por que equipes de aprendizado de máquina (machine learning) devem se importar)
Consistência descreve o que diferentes clientes observam ao ler dados.
Consistência forte vs consistência eventual
- Consistência forte (strong consistency): assim que uma escrita termina, todas as leituras subsequentes a veem.
- Consistência eventual (eventual consistency): réplicas convergem ao longo do tempo; leituras podem ver dados desatualizados.
Consistência eventual é comum em armazenamentos distribuídos de objetos e caches, e pode ser perfeitamente aceitável — se sua aplicação tolerar desatualização.
Consequências específicas de IA:
- Se atributos online forem eventualmente consistentes, seu modelo pode pontuar com atributos desatualizados (stale features), causando comportamento imprevisível.
- Se dados de treinamento forem construídos a partir de múltiplas fontes sem versionamento cuidadoso, você pode ter vazamento de rótulos (label leakage) ou junções inconsistentes.
Teorema CAP (CAP theorem) (interpretação prática)
O teorema CAP diz que, na presença de uma partição de rede (network partition), um sistema distribuído deve escolher entre:
- Consistência (C): todos os nós concordam com o mesmo valor ao mesmo tempo
- Disponibilidade (A): toda requisição recebe uma resposta (mesmo que desatualizada/incorreta)
- Tolerância a partição (P): o sistema continua operando apesar de mensagens perdidas/atrasadas
Como partições são inevitáveis, sistemas reais efetivamente escolhem entre comportamentos CP e AP sob partição.
Para sistemas de IA:
- Um registro de modelos ou armazenamento de metadados frequentemente prefere CP (melhor falhar do que servir o modelo errado).
- Um cache de embeddings pode preferir AP (melhor servir algo do que retornar erro).
Uma extensão útil é “PACELC”: se não houver partição, você ainda troca Latência vs Consistência — alta consistência frequentemente custa viagens de ida e volta adicionais.
Coordenação e consenso
Algumas decisões precisam ser tomadas uma vez e aceitas por todos:
- Quem é o líder?
- Quais nós fazem parte da membresia do cluster?
- Qual versão de modelo é a “atual”?
- Um job já foi efetivado (commit)?
Este é o domínio do consenso, tipicamente implementado por algoritmos como Raft ou Paxos (muitas vezes ocultos por trás de sistemas como etcd, ZooKeeper ou equivalentes gerenciados na nuvem).
Por que consenso aparece na infraestrutura de ML
Armazenamentos respaldados por consenso são frequentemente usados para:
- locks distribuídos (com cuidado),
- eleição de líder (por exemplo, um único scheduler ativo por vez),
- coordenar serviços particionados,
- armazenar metadados críticos (definições de atributos, versões de esquema, estado de execução).
A ideia-chave: consenso torna algumas operações logicamente de nó único novamente, ao custo de latência e vazão reduzida. Use isso para metadados e planos de controle, não para planos de dados de alto volume.
Padrões de tolerância a falhas que importam na prática
Sistemas distribuídos não são sobre evitar falhas; são sobre limitar o raio de impacto (blast radius) e recuperar automaticamente.
Modos de falha comuns em sistemas de IA
- Falha de nó: host de GPU morre no meio do treinamento; instância de inferência cai.
- Partição de rede: racks perdem conectividade; tráfego entre zonas é interrompido.
- Stragglers: um worker lento atrasa uma etapa de treinamento sincronizada.
- Efeito manada (thundering herd): muitos workers tentam novamente simultaneamente após uma indisponibilidade transitória.
- Artefatos corrompidos ou incompatíveis: checkpoint ruim, tokenizer/modelo incompatíveis.
Técnicas
- Checagens de saúde (health checks) + balanceamento de carga (load balancing): remover rapidamente réplicas de inferência não saudáveis.
- Contrapressão (backpressure): desacelerar produtores quando consumidores não conseguem acompanhar (crítico em ingestão por streaming).
- Disjuntores de circuito (circuit breakers): falhar rápido em vez de acumular requisições sobre um downstream moribundo.
- Anteparas (bulkheads): isolar recursos para que um modelo ou locatário (tenant) muito quente não deixe outros sem recursos.
- Criação de checkpoints (checkpointing): persistir o estado do treinamento para poder retomar após falha.
- Degradação graciosa (graceful degradation): cair para um modelo menor, resposta em cache ou heurística.
Criação de checkpoints se conecta diretamente ao comportamento numérico e de otimização; se você retomar o treinamento incorretamente (por exemplo, sem o estado do otimizador), a convergência muda. Veja Computação Numérica, Descida do Gradiente e Retropropagação para entender por que o estado do otimizador importa.
Pipelines de dados distribuídos para ML
Antes de o treinamento começar, dados precisam ser coletados, limpos, unidos e versionados — quase sempre com sistemas distribuídos.
Processamento em lote (batch processing) (offline)
Componentes típicos de stack:
- Armazenamento: armazenamentos de objetos (object stores) (S3/GCS/Azure Blob), HDFS, armazenamentos distribuídos tipo POSIX.
- Computação: Spark, Flink (batch), Ray, Dask ou motores de warehouse (Snowflake/BigQuery).
- Metadados/versionamento: manifestos de conjunto de dados, esquemas, linhagem (lineage); frequentemente armazenados em armazenamentos de metadados fortemente consistentes.
Um padrão comum:
- Eventos brutos chegam ao armazenamento de objetos (somente acréscimo (append-only)).
- Um job em lote agrega e valida dados.
- Saídas são escritas como arquivos particionados (por exemplo, Parquet) + um manifesto (manifest) identificando o snapshot exato.
- O treinamento lê pelo manifesto, não pela “pasta mais recente”, para garantir reprodutibilidade.
É aqui que tópicos centrais de CC como Algoritmos e Estruturas de Dados importam na prática: junções, ordenação, hashing e indexação determinam custo e latência do pipeline em escala. Veja também Complexidade para entender por que algumas operações (como ordenações globais) viram gargalos.
Processamento de fluxo (stream processing) (quase em tempo real)
Processamento de fluxo é útil para:
- computação de atributos quase em tempo real,
- monitoramento de deriva (drift) na qualidade dos dados,
- sinais de rotulagem online,
- manter índices atualizados (por exemplo, embeddings para recuperação).
Fluxos adicionam complexidade:
- ordenação é por partição, não global,
- reprocessamento deve lidar com duplicatas,
- operadores com estado precisam de checkpoints e recuperação.
Um requisito clássico é semântica exatamente-uma-vez (exactly-once semantics), mas muitos sistemas a aproximam usando entrega pelo menos uma vez (at-least-once delivery) + processamento idempotente, porque exatamente-uma-vez real atravessando efeitos colaterais é difícil.
Repositórios de atributos: o problema dos “dois mundos”
Um ponto de dor frequente em ML é a inconsistência offline/online:
- Atributos de treinamento offline computados em lote diferem de atributos de serviço online computados em streaming.
- Pequenas diferenças causam desvio entre treinamento e serviço (training/serving skew) e degradação silenciosa de desempenho.
Mitigação consciente de sistemas distribuídos:
- definir atributos uma vez e executar a mesma lógica em ambos os contextos quando possível,
- versionar definições de atributos,
- tratar dados de atributos como snapshots com viagem no tempo (correção em ponto no tempo (point-in-time correctness)),
- impor esquemas e restrições nas fronteiras.
Fundamentos de treinamento distribuído
Treinamento distribuído existe porque requisitos de computação e memória excedem um único dispositivo ou host.
As principais estratégias de paralelismo
Paralelismo de dados (data parallelism)
- Cada worker tem uma cópia completa do modelo.
- Cada um processa um shard diferente do minilote (mini-batch).
- Gradientes são agregados (por exemplo, redução coletiva (all-reduce)), então parâmetros são atualizados de forma síncrona.
- Comum em PyTorch DDP, Horovod; funciona bem até a comunicação dominar.
Paralelismo de modelo (model parallelism)
- O próprio modelo é dividido entre dispositivos (paralelismo tensorial (tensor parallelism), camadas particionadas).
- Necessário quando uma única réplica do modelo não cabe na memória.
Paralelismo de pipeline (pipeline parallelism)
- Divide camadas do modelo em estágios entre dispositivos.
- Micro-lotes fluem pelo pipeline para manter dispositivos ocupados.
Em treinamento de LLM (modelo de linguagem grande, large language model) em larga escala, você frequentemente combina os três, além de fragmentação do estado do otimizador (optimizer state sharding) (por exemplo, abordagens no estilo ZeRO (ZeRO-style approaches)).
Padrões de comunicação: servidor de parâmetros vs redução coletiva
Duas arquiteturas comuns:
Servidor de parâmetros (parameter server) (PS):
- Workers enviam gradientes para servidores; servidores atualizam parâmetros.
- Prós: pode ser mais flexível e assíncrono.
- Contras: PS pode virar gargalo; consistência/atualizações assíncronas complicam convergência.
Redução coletiva (comunicação coletiva, collective communication):
- Workers se comunicam peer-to-peer para somar/fazer média dos gradientes.
- Prós: rápido em interconexões de alta velocidade; amplamente usado em SGD síncrono.
- Contras: sensível a stragglers; exige rede eficiente (por exemplo, NCCL sobre InfiniBand).
O treinamento frequentemente é limitado não por FLOPs, mas por bytes movimentados — uma realidade de sistemas distribuídos.
Stragglers e sincronização
Treinamento síncrono espera pelo worker mais lento a cada etapa. Causas:
- vizinhos ruidosos em ambientes de nuvem,
- variabilidade no carregamento de dados,
- limitação térmica de hardware,
- congestionamento de rede.
Mitigações incluem:
- pipelines de entrada melhores (prefetch, caching, sharding),
- acumulação de gradientes (gradient accumulation) (menos pontos de sincronização),
- treinamento elástico (elastic training) (ajustando workers dinamicamente),
- posicionamento cuidadoso/agendamento sensível à topologia (topology-aware scheduling).
Criação de checkpoints e recuperação
Jobs de treinamento falham — então uma criação de checkpoints robusta é essencial.
Pontos-chave:
- Salve pesos do modelo, estado do otimizador e progresso de treinamento (step, sementes de RNG se necessário).
- Use semântica de commit atômico (atomic commit semantics) para checkpoints (escreva em temporário e, depois, renomeie/efetive).
- Mantenha metadados (qual checkpoint é o “último bom”) em um armazenamento fortemente consistente.
Em ambientes distribuídos, você também precisa decidir:
- Quem escreve checkpoints (um rank vs checkpoints particionados)?
- Onde eles ficam (armazenamento de objetos vs sistema de arquivos distribuído)?
- Com que frequência (troca entre overhead e trabalho perdido)?
Inferência distribuída em produção
Servir modelos é um problema de sistemas distribuídos mesmo quando o modelo roda em uma única GPU — porque disponibilidade, escalabilidade e latência exigem múltiplas réplicas e serviços de suporte.
Arquitetura típica de serving
Uma stack de inferência em produção frequentemente inclui:
- Roteamento de requisições: gateway de API / balanceador de carga.
- Camada de serving de modelos: réplicas sem estado (stateless) executando Triton, vLLM, TGI, servidores customizados etc.
- Recuperação de atributos (opcional): repositório de atributos online, caches, serviços de consulta de embeddings.
- Recuperação (opcional): banco de dados vetorial / serviço de ANN para geração aumentada por recuperação (RAG, retrieval-augmented generation).
- Pós-processamento: regras de negócio, filtros de segurança, formatação.
- Registro e monitoramento: traces, métricas, logs de auditoria.
Cada componente adiciona saltos de rede e modos de falha; gerenciar latência de cauda torna-se tão importante quanto a velocidade bruta do modelo.
Latência, vazão e batching
Sistemas de inferência fazem trocas constantes entre:
- Latência: tempo por requisição
- Vazão: requisições por segundo
- Custo: utilização de GPU e superprovisionamento
Batching dinâmico (dynamic batching) melhora vazão ao agrupar requisições, mas aumenta latência de enfileiramento (queueing latency). Muitas stacks de serving implementam batching limitado (bounded batching) (batch até N requisições ou esperar até T milissegundos).
Nota específica de LLM: decodificação autorregressiva (autoregressive decoding) introduz dependência sequencial; stacks de serving otimizam com técnicas como batching contínuo (continuous batching) e gestão de cache KV (KV-cache), que criam pressão adicional de estado compartilhado e memória.
Serviços sem estado vs com estado
Réplicas sem estado são mais fáceis de escalar e substituir. Mas inferência de IA frequentemente envolve estado:
- contexto de sessão,
- caches KV,
- contadores de limite de taxa,
- atributos online,
- perfis de personalização.
Um padrão comum é manter a camada de serving o mais sem estado possível e mover o estado para armazenamentos dedicados (com estratégias explícitas de consistência e cache). Quando o estado precisa ficar no processo (por exemplo, cache KV), você precisa de roteamento cuidadoso e políticas de evicção (eviction policies).
Implantações seguras: canários e rollback
Atualizações de modelo são “releases de software” com risco adicional:
- regressões de qualidade,
- mudanças de distribuição,
- incompatibilidades de prompt/template,
- mudanças de tokenizer.
Práticas de sistemas distribuídos ajudam:
- Implantação canário (canary deploy): enviar uma pequena porcentagem do tráfego para o novo modelo.
- Implantação sombra (shadow deploy): executar o novo modelo sem afetar respostas ao usuário, comparar saídas.
- Artefatos versionados: binários e configs de modelo imutáveis, referenciados por hash.
- Rollback rápido: manter versões anteriores aquecidas, se possível.
Observabilidade: tornando sistemas de IA distribuídos depuráveis
Quando algo dá errado em um sistema de IA distribuído, você raramente obtém um único rastreamento de pilha (stack trace) óbvio. Você precisa de observabilidade (observability):
- Métricas: percentis de latência (p50/p95/p99), taxas de erro, utilização de GPU, profundidade de fila, taxa de acerto de cache.
- Logs: logs estruturados com IDs de requisição, versão do modelo, versões de atributos.
- Rastreamento distribuído (distributed tracing): visibilidade ponta a ponta entre serviços (crítico para diagnosticar latência de cauda).
- Monitoramento de qualidade de dados: deriva, taxa de ausência (missingness), violações de esquema.
- Auditabilidade (auditability): qual versão de modelo produziu qual saída (frequentemente exigido para conformidade).
Uma dica prática: sempre propague um ID de correlação (correlation ID) da borda por todas as chamadas downstream e inclua-o em logs/traces.
Segurança e multitenância (breve, mas importante)
Plataformas de IA atendem cada vez mais múltiplas equipes ou clientes. Sistemas distribuídos devem lidar com:
- Autenticação/autorização entre serviços (mTLS, tokens assinados).
- Criptografia em trânsito e em repouso (especialmente para dados de treinamento sensíveis).
- Gestão de segredos (evite embutir chaves em contêineres ou código).
- Isolamento de recursos (evitar que o job de treinamento de um locatário consuma recursos e prejudique a inferência).
Segurança não é separada de confiabilidade: incidentes frequentemente começam como problemas de confiabilidade e viram problemas de segurança (ou vice-versa).
Exemplos práticos de design
Exemplo 1: Particionando um cache de embeddings com hashing consistente
Suponha que você sirva um modelo de recomendação que frequentemente consulta embeddings de usuário e item. Um cache centralizado vira gargalo; um cluster de cache distribuído ajuda.
- Use hashing consistente em
(entity_type, entity_id)para mapear chaves para nós de cache. - Replique chaves quentes ou mantenha um pequeno cache local por réplica de inferência para reduzir saltos.
- Acompanhe taxa de acerto de cache e desbalanceamento; introduza mitigação de “chave quente” se um pequeno conjunto dominar.
Conceitos-chave de sistemas distribuídos: particionamento, replicação, desbalanceamento, caching, recuperação de falhas.
Exemplo 2: Snapshots de conjunto de dados de treinamento para reprodutibilidade
Você constrói dados diários de treinamento a partir de logs + rótulos + metadados de usuário.
- Armazene logs brutos como somente acréscimo.
- Produza um conjunto de dados diário como Parquet particionado mais um manifesto listando partições exatas e versões de esquema.
- Salve o ID do manifesto nos metadados da execução de treinamento (em um armazenamento de metadados consistente).
- Se uma tabela downstream atrasar, você pode atrasar o snapshot (favorecer consistência) ou prosseguir com dados parciais (favorecer disponibilidade), mas você torna a escolha explícita.
Conceitos-chave: consistência, versionamento, coordenação de metadados, repetibilidade.
Exemplo 3: Novas tentativas de inferência sem efeitos colaterais duplicados
Seu endpoint de inferência também escreve um registro de “impressão” (impression) para analytics. Um timeout do cliente dispara uma nova tentativa; você não pode contar duas vezes.
- Exija uma chave de idempotência fornecida pelo cliente (ou gere uma na borda).
- Deduplicate escritas por chave no ponto de ingestão de analytics.
- Separe o caminho de resposta de inferência do logging com mensageria assíncrona para reduzir latência de cauda.
Conceitos-chave: novas tentativas, tempos limite, idempotência, desacoplamento via mensageria.
Como isso se conecta a outras fundações centrais de CC
Sistemas distribuídos ficam ao lado e dependem de outros fundamentos neste wiki:
- Programação para Aprendizado de Máquina: primitivas de concorrência, I/O assíncrono e ferramentas práticas de sistemas.
- Computação Numérica: precisão, determinismo e como checkpoint/retomada afeta o comportamento do treinamento.
- Algoritmos e Estruturas de Dados: hashing, indexação, ordenação, estratégias de junção — críticos para pipelines escaláveis.
- Complexidade: por que certas operações (coordenação global, embaralhamentos all-to-all) viram paredes de escalabilidade.
- Busca: muitos componentes de recuperação e indexação dependem de ideias de busca; recuperação distribuída introduz restrições adicionais de sistemas.
Principais aprendizados
- Sistemas distribuídos são inevitáveis em IA porque dados, computação de treinamento e serving em produção excedem limites de uma única máquina.
- Os desafios centrais são falha parcial, redes não confiáveis, ausência de um relógio global e overhead de coordenação.
- A maioria das decisões de design se reduz a trocas explícitas: consistência vs disponibilidade, latência vs vazão, simplicidade vs escalabilidade.
- O sucesso prático depende de padrões como idempotência, criação de checkpoints, particionamento, replicação, observabilidade e implantação segura.
- Entender esses fundamentos torna você melhor em diagnosticar incidentes reais de IA: instabilidade de treinamento, desbalanceamento de dados, latência de cauda e desalinhamentos silenciosos entre treinamento e serviço frequentemente são problemas de sistemas distribuídos usando uma máscara de ML.