Redis Cache (Cache Aside)
TTL, eviction e invalidação
Configurando expiração e invalidação para evitar dado stale no customer-service.
Nesta aula você vai
- Definir TTL adequado para perfil de leitura de cliente
- Configurar eviction policy do Redis no ambiente local
- Invalidar cache em update e delete de cliente
TTL, eviction e invalidação
Objetivos
- Evitar dados desatualizados no cache.
- Manter memória Redis sob controle.
- Garantir consistência após escrita no banco.
Pré-requisitos
- Aula anterior (
cache-aside-por-que-como) concluída. - Redis com persistência e métricas habilitadas.
- Operações
PUTeDELETEnocustomer-service.
Conceito
TTL limita tempo de vida. Eviction define como Redis remove chaves quando a memória acaba. Invalidação garante que um dado alterado no banco não continue sendo servido do cache antigo.
Estrutura de arquivos
infra/redis/
└── redis.conf
services/customer-service/src/main/java/br/com/sistemasamo/customer/
├── cache/CustomerCacheRepository.java
└── service/CustomerService.java
Passo a passo
- Configure Redis (
infra/redis/redis.conf):
maxmemory 256mb
maxmemory-policy allkeys-lru
- Defina TTL com jitter no cache:
public void put(CustomerResponse value) {
try {
long jitterSeconds = ThreadLocalRandom.current().nextLong(0, 30);
Duration ttl = Duration.ofMinutes(10).plusSeconds(jitterSeconds);
redis.opsForValue().set(key(value.id()), objectMapper.writeValueAsString(value), ttl);
} catch (Exception ignored) {
}
}
- Invalide após update e delete em
CustomerService.java:
@Transactional
public CustomerResponse updateCustomer(String id, UpdateCustomerRequest request) {
Customer entity = customerRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Cliente não encontrado: " + id));
entity.setName(request.name());
entity.setEmail(request.email());
customerRepository.save(entity);
cacheRepository.evict(id);
return mapper.toResponse(entity);
}
@Transactional
public void deleteCustomer(String id) {
customerRepository.deleteById(id);
cacheRepository.evict(id);
}
- Método de remoção:
public void evict(String customerId) {
try {
redis.delete(key(customerId));
} catch (Exception ignored) {
}
}
Como testar
docker compose up -d redis customer-service postgres
curl -s http://localhost:8081/customers/c-2 | jq
curl -s -X PUT http://localhost:8081/customers/c-2 \
-H "Content-Type: application/json" \
-d '{"name":"Cliente Novo","email":"novo@sistemasamo.com"}' | jq
curl -s http://localhost:8081/customers/c-2 | jq
No Redis CLI:
docker compose exec redis redis-cli TTL customer-service:customer:c-2
Dicas de projeto
- Use jitter no TTL para reduzir cache stampede.
- Prefira invalidação explícita em dados críticos.
- Acompanhe
evicted_keyseused_memorynas métricas.
Erros comuns
- Aplicar
TTL=0sem querer (chave sem expiração). - Atualizar banco e esquecer invalidação.
- Usar policy
noevictioncom memória subdimensionada.
Resumo
Você configurou TTL, eviction e invalidação de forma prática, deixando o cache rápido sem abrir mão da consistência.