Este projeto implementa um sistema de cache utilizando a estratégia write-back com Redis e PostgreSQL. O sistema foi desenvolvido como parte da atividade 2 do módulo 2 da disciplina ESDB3, demonstrando como implementar um cache que prioriza a velocidade de escrita através de persistência assíncrona.
- Cache Write-Back (Redis): Armazena dados temporariamente e gerencia operações de escrita
- Fila de Persistência (Bull.js): Processa operações assíncronas para o banco de dados
- Banco de Dados (PostgreSQL): Armazenamento persistente final
- API REST (Express.js): Interface para operações CRUD
- Sistema de Locks: Controla concorrência e evita condições de corrida
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Cliente │───▶│ API REST │───▶│ Write-Back │───▶│ Fila │
└─────────────┘ └─────────────┘ │ Cache │ │Persistência │
└─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Redis │ │ PostgreSQL │
└─────────────┘ └─────────────┘
- Docker e Docker Compose
- Node.js 18+ (para desenvolvimento local)
- Clone e acesse o diretório:
git clone <repository>
cd write-back-cache-system- Inicie os serviços:
docker-compose up -d- Acesse a aplicação:
- API: http://localhost:3000
- Health Check: http://localhost:3000/api/admin/health
- Estatísticas do Cache: http://localhost:3000/api/admin/cache/stats
- Instale dependências:
npm install- Configure variáveis de ambiente:
cp env.example .env
# Edite o arquivo .env conforme necessário- Inicie Redis e PostgreSQL:
docker-compose up redis postgres -d- Execute a aplicação:
npm run dev| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/products |
Lista produtos com paginação |
| GET | /api/products/:id |
Busca produto por ID |
| POST | /api/products |
Cria novo produto |
| PUT | /api/products/:id |
Atualiza produto |
| DELETE | /api/products/:id |
Deleta produto |
| PATCH | /api/products/:id/stock |
Atualiza estoque |
| GET | /api/products/category/:category |
Busca por categoria |
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/admin/health |
Verifica saúde do sistema |
| GET | /api/admin/cache/stats |
Estatísticas do cache |
| GET | /api/admin/cache/dirty-keys |
Chaves pendentes de persistência |
| POST | /api/admin/cache/force-sync |
Força sincronização |
| DELETE | /api/admin/cache/clear |
Limpa todo o cache |
| GET | /api/admin/cache/key/:key |
Inspeciona chave específica |
curl -X POST http://localhost:3000/api/products \\
-H "Content-Type: application/json" \\
-d '{
"name": "Smartphone Galaxy",
"description": "Smartphone Android com 128GB",
"price": 1299.99,
"stock_quantity": 50,
"category": "Electronics"
}'curl -X PATCH http://localhost:3000/api/products/1/stock \\
-H "Content-Type: application/json" \\
-d '{
"quantity": 10,
"operation": "add"
}'curl http://localhost:3000/api/admin/cache/stats- Escrita Rápida: Dados são escritos imediatamente no cache Redis
- Marcação Dirty: Chave é marcada para persistência posterior
- Resposta Imediata: Cliente recebe confirmação sem esperar o banco
- Persistência Assíncrona: Fila processa dados para PostgreSQL em background
- Controle de Versão: Sistema evita conflitos com timestamps e versões
- ✅ Latência Mínima: Escritas são extremamente rápidas
- ✅ Alto Throughput: Suporta muitas operações simultâneas
- ✅ Tolerância a Falhas: Dados ficam seguros no cache mesmo se o banco estiver lento
- ✅ Otimização de Recursos: Agrupa escritas para reduzir carga no banco
- ❌ Risco de Perda: Dados podem ser perdidos se o cache falhar antes da persistência
- ❌ Complexidade: Requer controle cuidadoso de concorrência
- ❌ Consistência Eventual: Dados podem estar temporariamente inconsistentes
- ❌ Debugging Complexo: Mais difícil rastrear problemas de dados
- Cada chave do cache tem seu próprio mutex
- Evita condições de corrida durante escritas simultâneas
- Garante atomicidade das operações
- Cada operação recebe um timestamp e número de versão
- Permite detectar e resolver conflitos
- Evita sobrescrita de dados mais recentes
Tempo | Operação A | Operação B | Resultado
---------|-------------------|-------------------|----------
T1 | Lê produto (v1) | Lê produto (v1) | Ambos têm v1
T2 | Modifica preço | Modifica estoque | -
T3 | Escreve (v2) | - | Cache tem v2
T4 | - | Escreve (v3) | Cache tem v3 (mais recente)
T5 | Persiste v2 | Persiste v3 | Banco fica com v3
- Retry: 3 tentativas com backoff exponencial
- Prioridade: DELETE > INSERT > UPDATE
- Delay: 1 segundo para permitir write coalescing
- Cleanup: Remove jobs antigos automaticamente
- Logs detalhados de todas as operações
- Métricas de performance disponíveis via API
- Alertas para falhas de persistência
✅ Cache HIT para products:123
❌ Cache MISS para products:456
🔄 Chave products:123 marcada para persistência
✍️ Escrevendo no cache: products:789
💾 Persistência concluída: UPDATE para products:123
- Total de chaves no cache
- Número de chaves dirty
- Número de chaves deletadas
- Contadores de hits/misses
- Tempo de resposta das operações
# Terminal 1: Cria muitos produtos
for i in {1..100}; do
curl -X POST http://localhost:3000/api/products -H "Content-Type: application/json" -d "{\"name\":\"Produto $i\",\"price\":$((RANDOM%1000))}";
done
# Terminal 2: Monitora estatísticas
watch -n 1 'curl -s http://localhost:3000/api/admin/cache/stats | jq'# Atualiza mesmo produto simultaneamente
seq 1 50 | xargs -P 10 -I {} curl -X PATCH http://localhost:3000/api/products/1/stock -H "Content-Type: application/json" -d '{"quantity":1,"operation":"add"}'E-commerce com atualizações frequentes de estoque:
- Milhares de operações de estoque por segundo
- Necessidade de resposta imediata para usuários
- Tolerância a pequenos atrasos na persistência
- Dados podem ser reconstruídos a partir de logs
Sistema bancário de transferências:
- Necessidade de consistência imediata
- Zero tolerância a perda de dados
- Regulamentações exigem persistência imediata
- Auditoria requer garantias de durabilidade
# Cache
CACHE_TTL=3600 # TTL padrão em segundos
SYNC_INTERVAL=5000 # Intervalo de sincronização em ms
# Performance
MAX_RETRIES=3 # Máximo de tentativas na fila
BATCH_SIZE=100 # Tamanho do lote para persistência
WRITE_COALESCING_DELAY=1000 # Delay para agrupamento em ms
# Monitoramento
LOG_LEVEL=info # Nível de log (debug, info, warn, error)
ENABLE_METRICS=true # Habilita coleta de métricas- Write Coalescing: Agrupa escritas da mesma chave
- Batch Processing: Processa múltiplas operações juntas
- Connection Pooling: Reutiliza conexões do banco
- Memory Optimization: Limpa mutexes não utilizados
# Verifica conexão Redis
docker exec -it cache_redis redis-cli ping
# Verifica logs do container
docker logs cache_app# Verifica fila de trabalhos
curl http://localhost:3000/api/admin/cache/dirty-keys
# Força sincronização
curl -X POST http://localhost:3000/api/admin/cache/force-sync# Inspeciona chave específica
curl http://localhost:3000/api/admin/cache/key/products:123
# Verifica estatísticas de mutexes
curl http://localhost:3000/api/admin/cache/stats- Fork o projeto
- Crie uma branch para sua feature
- Commit suas mudanças
- Push para a branch
- Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
- ESDB3 At2 - Implementação do sistema de cache write-back
⚡ Sistema de Cache Write-Back - Velocidade máxima para escritas com persistência assíncrona confiável!