A progressive Node.js framework for building efficient and scalable server-side applications.
Projeto de estudo implementando padrões de escalabilidade com NestJS, demonstrando técnicas essenciais para construir aplicações de alta performance e disponibilidade.
Este projeto implementa uma API REST de gerenciamento de produtos utilizando padrões de escalabilidade modernos, incluindo Cache Aside com Redis e Replicação Master-Slave de banco de dados PostgreSQL.
O que é?
- Padrão onde a aplicação gerencia o cache de forma explícita
- Os dados são buscados do cache primeiro; se não existirem (Cache Miss), busca-se do banco de dados
Benefícios:
- ⚡ Redução de latência: Respostas até 100x mais rápidas em Cache Hit
- 📉 Menor carga no banco: Reduz consultas repetidas ao PostgreSQL
- 💰 Economia de recursos: Menos processamento e I/O no banco de dados
- 🔄 Controle total: A aplicação decide quando invalidar o cache
Como funciona no projeto:
// 1ª requisição GET /products → Cache Miss → Busca do banco → Salva no cache
// 2ª requisição GET /products → Cache Hit → Retorna do Redis (muito mais rápido!)
// POST /products → Cria produto → Invalida o cache automaticamenteConfiguração:
- Redis: Cache em memória (porta 6379)
- TTL: 5 minutos (300 segundos)
- Chave: products:all
O que é?
- Arquitetura com um banco Master (escrita) e um ou mais Replicas (leitura)
- Replicação streaming assíncrona do Master para Replica
Benefícios:
- 📊 Escalabilidade horizontal: Distribui carga de leitura entre múltiplas réplicas
- 🎯 Separação de responsabilidades: Escrita no Master, leitura nas Replicas
- 🛡️ Alta disponibilidade: Replica pode ser promovida a Master em caso de falha
- ⚖️ Balanceamento de carga: Múltiplas réplicas podem atender requisições de leitura
Como funciona no projeto:
// POST /products → Escreve no Master (porta 5432)
// GET /products → Lê da Replica (porta 5433)
// Replicação acontece automaticamente via WAL (Write-Ahead Logging)Configuração:
- PostgreSQL Master: Escrita (porta 5432)
- PostgreSQL Replica: Leitura (porta 5433)
- Replicação: Streaming com WAL
O que é?
- Interface visual oficial da Redis para monitorar e gerenciar cache
Benefícios:
- 👀 Visualização em tempo real: Veja as chaves e valores do cache
- 🔍 Análise de TTL: Monitore tempo de expiração dos dados
- 📈 Métricas: Acompanhe hits, misses e performance
- 🛠️ Debug: Execute comandos Redis manualmente
Acesso:
- URL: http://localhost:5540
- Conexão: redis://scaling_redis:6379
┌─────────────┐
│   Cliente   │
└──────┬──────┘
       │
       ▼
┌─────────────────────────────────┐
│       NestJS Application        │
│  ┌──────────┐    ┌───────────┐ │
│  │Controller│───▶│  Service  │ │
│  └──────────┘    └─────┬─────┘ │
│                        │        │
│         ┌──────────────┼───────────────┐
│         ▼              ▼               │
│    ┌────────┐    ┌──────────┐         │
│    │ Redis  │    │TypeORM   │         │
│    │ Cache  │    │Repository│         │
│    └────────┘    └────┬─────┘         │
└─────────────────────────┼──────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
   ┌─────────┐      ┌──────────┐    ┌──────────┐
   │  Redis  │      │PostgreSQL│    │PostgreSQL│
   │         │      │  Master  │───▶│ Replica  │
   │(Cache)  │      │ (Write)  │    │  (Read)  │
   └─────────┘      └──────────┘    └──────────┘
   Port: 6379       Port: 5432      Port: 5433
- Node.js 18+
- Docker & Docker Compose
- npm ou yarn
# 1. Clone o repositório
git clone https://github.com/vgransotto/scaling-db-patterns.git
cd scaling-patterns
# 2. Instale as dependências
npm install
# 3. Suba os serviços Docker (Redis, PostgreSQL Master e Replica, RedisInsight)
docker compose up -d
# 4. Verifique se os serviços estão rodando
docker compose ps
# 5. Configure as variáveis de ambiente (já está criado o .env)
# Verifique o arquivo .env na raiz do projeto
# 6. (Opcional) Execute o seed para popular o banco com dados iniciais
npm run seed
# 7. Inicie a aplicação em modo desenvolvimento
npm run start:devO projeto inclui um sistema de seed para popular o banco de dados com produtos de exemplo usando Faker.js.
Executar o seed:
npm run seedO que o seed faz:
- Verifica quantos produtos já existem no banco
- Cria produtos até atingir o total de 5 produtos
- Gera dados realistas usando Faker.js (nome, descrição, preço, estoque)
- Invalida automaticamente o cache do Redis após inserir os dados
- Não duplica produtos se já existirem 5 ou mais
Exemplo de saída:
🚀 Starting database seed...
✅ Database connection established
📊 Current products in database: 0
🌱 Seeding 5 products...
   📦 1. Sleek Metal Gloves - $517.79 (Stock: 30)
   📦 2. Elegant Steel Shoes - $416.45 (Stock: 136)
   📦 3. Handcrafted Cotton Bacon - $234.56 (Stock: 89)
   📦 4. Rustic Plastic Hat - $89.99 (Stock: 45)
   📦 5. Modern Bronze Keyboard - $678.23 (Stock: 12)
✅ Successfully seeded 5 products!
📊 Total products in database: 5
🔄 Connecting to Redis...
✅ Cache invalidated successfully!
✅ Seed completed successfully!
Arquivo .env na raiz do projeto:
NODE_ENV=development
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
CACHE_TTL=300
# PostgreSQL Master (Escrita)
DB_MASTER_HOST=localhost
DB_MASTER_PORT=5432
DB_MASTER_USER=postgres
DB_MASTER_PASS=postgres_password
# PostgreSQL Replica (Leitura)
DB_SLAVE_HOST=localhost
DB_SLAVE_PORT=5433
DB_SLAVE_USER=postgres
DB_SLAVE_PASS=postgres_password
# Database
DB_NAME=scaling_dbUse o arquivo api.http na raiz do projeto (extensão REST Client no VS Code):
### Criar um produto (Cache será invalidado)
POST http://localhost:3000/products
Content-Type: application/json
{
  "name": "Product 1",
  "description": "Description for Product 1",
  "price": 100,
  "stock": 50
}
### Listar produtos (1ª vez: Cache Miss, 2ª vez: Cache Hit)
GET http://localhost:3000/products# Ver todas as chaves no Redis
docker exec -it scaling_redis redis-cli KEYS "*"
# Ver o valor de uma chave específica
docker exec -it scaling_redis redis-cli GET "products:all"
# Verificar TTL de uma chave
docker exec -it scaling_redis redis-cli TTL "products:all"
# Ou use o RedisInsight no navegador
# http://localhost:5540# Conectar ao Master
docker exec -it scaling_postgres_master psql -U postgres -d scaling_db
# Verificar status da replicação (no Master)
SELECT client_addr, state, sent_lsn, write_lsn, sync_state 
FROM pg_stat_replication;
# Conectar à Replica
docker exec -it scaling_postgres_replica psql -U postgres -d scaling_db
# Verificar se está em recovery mode (no Replica)
SELECT pg_is_in_recovery();
# Verificar lag da replicação (no Replica)
SELECT NOW() - pg_last_xact_replay_timestamp() AS replication_lag;- Acesse: http://localhost:5540
- Adicione conexão: redis://scaling_redis:6379
# Ver logs em tempo real
npm run start:dev
# Busque por:
# - "Cache Hit" → Dados retornados do cache
# - "Cache Miss" → Dados buscados do banco
# - "Cache invalidated" → Cache foi limpo# Subir todos os serviços
docker compose up -d
# Ver logs de todos os serviços
docker compose logs -f
# Ver logs de um serviço específico
docker compose logs -f redis
docker compose logs -f postgres_master
# Parar todos os serviços
docker compose down
# Parar e remover volumes (limpar todos os dados)
docker compose down -v
# Reiniciar um serviço específico
docker compose restart redis# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:covEste projeto já apresenta uma estrutura robusta para aplicações simples e soluciona diversos problemas de escalabilidade e disponibilidade. No entanto, existem várias otimizações que poderiam ser implementadas para cenários mais complexos:
- Implementar cache individual por produto (ex: product:{id})
- Estratégia de Cache LRU (Least Recently Used) para produtos populares
- Cache com TTL diferenciado baseado em popularidade
- Métricas de hit rate por produto para análise de performance
- Implementar paginação com limiteoffset
- Cache por página (ex: products:page:1,products:page:2)
- Cursor-based pagination para melhor performance em datasets grandes
- Metadados de paginação (total de items, total de páginas, etc.)
- Lógica de elegibilidade para promover Replica a Master automaticamente
- Implementar health checks e monitoramento contínuo
- Adicionar múltiplas Replicas para maior redundância
- Configurar Patroni ou Repmgr para gerenciamento automático de failover
- Load balancer entre múltiplas Replicas (ex: HAProxy, PgBouncer)
- Rate limiting para proteção contra abuso
- Compressão de dados no cache
- Monitoramento com Prometheus e Grafana
- Logs estruturados com ELK Stack
- Circuit breaker para resiliência
- Testes de carga e benchmarks
Apesar das melhorias sugeridas, este projeto já apresenta:
✔️ Arquitetura escalável com separação de leitura/escrita
✔️ Cache eficiente com Redis reduzindo latência e carga no banco
✔️ Replicação de dados garantindo disponibilidade
✔️ Monitoramento visual com RedisInsight
✔️ Base sólida para aplicações de produção de pequeno a médio porte
Esta implementação é adequada para aplicações simples e médias, resolvendo os principais desafios de escalabilidade e disponibilidade de forma eficaz. Para aplicações de grande porte ou com requisitos específicos, as melhorias sugeridas acima podem ser implementadas gradualmente conforme a necessidade.