é o processo de definir a arquitetura, componentes, módulos, interfaces e dados de um sistema para atender a requisitos específicos. é a ponte entre a teoria da ciência da computação e a prática de construir sistemas robustos e escaláveis.
enquanto a arquitetura de software foca na estrutura interna e padrões de código, o system design foca na infraestrutura, comunicação entre componentes e trade-offs em larga escala.
pilares do system design
escalabilidade
é a capacidade do sistema de crescer e lidar com mais carga.
- vertical (scale up): adicionar mais poder (CPU/RAM) a uma única máquina.
- pró: simples.
- contra: limite físico e SPOF (single point of failure)
- horizontal (scale out): adicionar mais máquinas ao pool de recursos.
- pró: escalabilidade quase ilimitada
- contra: complexidade de gerenciamento
load balancing
componente crítico para escalabilidade horizontal. distribui o tráfego de rede entre vários servidores para garantir que nenhum fique sobrecarregado.
- algoritmos comuns: round robin, least connections, IP hash.
- pode atuar na Camada 4 (transporte/TCP) ou camada 7 (aplicação/HTTP).
caching
armazenar dados acessados frequentemente em memória (rápida) para reduzir a carga no banco de dados (lento).
- locais: browser, CDN, API Gateway, banco de dados
- ferramentas: Redis, Memcached.
- desafio: invalidação de cache
"existem apenas duas coisas difíceis na ciência da computação: invalidação de cache e nomear as coisas" — Phil Karlton
bancos de dados e persistência
a escolha entre SQL (relacional) e NoSQL (não-relacional) define a flexibilidade e a consistência do sistema.
- replication: master-slave (leitura escala, escrita centralizada) vs. master-master
- sharding: dividir o banco em pedaços menores distribuídos em servidores diferentes
- teorema CAP: em um sistema distribuído, você só pode ter 2 de 3:
- consistency: todos vêem os mesmos dados ao mesmo tempo.-
- availability: o sistema sempre responde (mesmo com dados velhos)
- partition tolerance: o sistema funciona mesmo se a rede falhar
na prática, em sistemas distribuídos, P é obrigatório, então a escolha é entre CP (bancos fortes como Postgres) ou AP (bancos flexíveis como Cassandra/Dynamo).
comunicação
como os serviços conversam entre si. pode ser síncrona ou assíncrona.
- síncrona (blocking): HTTP/REST, gRPC, GraphQL. o cliente espera a resposta
- assíncrona (non-blocking): message queues (RabbitMQ, Kafka) e event-driven architecture. o cliente envia e segue a jprnada; o processamento ocorre em background. é e essencial para desacoplamento e load leveling.
framework para decisões
requisitos
- funcionais: o que o sistema faz?
- não-funcionais: qual a latência aceitável? quantos usuários simultâneos (DAU/MAU)? consistência ou disponibilidade?
estimativas (back-of-the-envelope)
- cálculo rápido de armazenamento e banda de rede necessários./
high-level desigm
desenhar as grandes caixas (ex: LB → Web Server → DB)
design detalhado
aprofundamento nos gargalos. (como escalar o banco? como lidar com falhas?)
identificar gargalos
onde o sistema vai quebrar primeiro? (SPOFs, latência de rede)
a regra de ouro
mantenha simples até que precise ser complexo. tudo na arquitetura de software é um trade-off.