🧠FFVAcademy

Caching: ElastiCache, DAX e Padrões

12 min de leitura·+60 XP

Cache é o pattern mais antigo e mais efetivo para reduzir latência e custo de banco. Mas implementar mal resulta em dados stale, invalidação confusa e bugs sutis. O SAA cobra: escolha de produto (Redis × Memcached × DAX × CloudFront), escolha de padrão (cache-aside × write-through × write-behind) e interpretação de métricas.

📘 High-Performing· 24%
📘 Cost-Optimized· 20%

ElastiCache: Redis vs Memcached

DimensãoRedisMemcached
EstruturasStrings, lists, sets, sorted sets, hashes, streams, hyperloglog, geoApenas key-value string
Multi-threadSingle-threaded (1 core por node)Multi-threaded (escala vertical melhor)
PersistênciaRDB snapshots + AOF logNenhuma (puramente in-memory)
ReplicaçãoRead replicas + cluster modeSharding client-side, sem replicação
High AvailabilityMulti-AZ com automatic failoverNão nativo
Pub/SubSimNão
TransactionsSim (MULTI/EXEC)Não
Encryption in-transit / at-restSim (TLS + KMS)In-transit sim, at-rest não
Caso de usoSession store, leaderboards, filas, geo, pub/subCache puro simples, multi-thread, sem persistência
💡
Regra prática: na dúvida, escolha Redis. Memcached só ganha se você precisa estritamente de multithread e não liga para persistência/replicação. Exame favorece Redis em quase todo cenário.

Redis: Cluster Mode Disabled vs Enabled

FeatureCluster DisabledCluster Enabled
Shards1 shardAté 500 shards
Dataset máximoLimitado ao tamanho de 1 node (~600GB)Horizontal scaling — petabytes
ClientConexão simplesPrecisa de cluster-aware client
Primary failoverAuto com Multi-AZAuto por shard
BackupSnapshot completoSnapshot por shard
CasoSessions, cache de API pequeno-médioDatasets grandes, high throughput distribuído

DAX — cache nativo do DynamoDB

DAX é um cache in-memory write-through compatível com a API do DynamoDB. A aplicação troca o endpoint e ganha latência μs (microssegundos). Roda em cluster de nodes na VPC.

🗺️ DAX como item cache + query cache
     App (DynamoDB SDK)
          │
          ▼
     ┌─────────┐
     │   DAX   │──── Item Cache (GetItem / BatchGetItem)
     │ cluster │──── Query Cache  (Query / Scan)
     └────┬────┘
          │ miss
          ▼
     DynamoDB  ← write-through: DAX propaga PUT/UPDATE/DELETE
Item Cache TTLDefault 5min. Configurável por cluster.
Query Cache TTLDefault 5min. Invalidado em writes na tabela.
ConsistênciaEventual nos reads cached. Strong reads fazem bypass do cache.
Casos ideaisLeitura extremamente alta de items "quentes" (leaderboard, top products). Reduz custo de RCU significativamente.
Não recomendadoWrite-heavy (não dá benefício, só custo) e dados totalmente dispersos (hit rate baixo).
⚠️
DAX ≠ ElastiCache: DAX só fala API DynamoDB. Para RDS/Aurora você usa ElastiCache. Alguns candidatos erram pensando que DAX acelera qualquer query.

CloudFront — cache de borda para HTTP/S

CloudFront não é “o mesmo que ElastiCache mas HTTP”. É CDN global com POPs em ~450 cidades. Cache é controlado por cache policy (TTL + keys baseadas em query string/headers/cookies) e origin request policy (o que forward para a origem).

BehaviorsRotas por path pattern (ex: /api/* vs /static/*) com policies diferentes.
InvalidationAPI para forçar expiração de paths. Primeiros 1.000 paths/mês grátis, depois $0,005/path.
Origin ShieldCamada intermediária de cache — útil para reduzir requests à origem em multi-POP.
Signed URLs/CookiesControle de acesso temporário para conteúdo premium.
Field-Level EncryptionCriptografa campos específicos do POST (ex: número do cartão) com chave pública da origem.

Padrões de cache — decor e aplique

PadrãoComo funcionaPrósContras
Cache-Aside (Lazy)App verifica cache; miss → busca DB → popula cacheSimples, cacheia apenas o usadoPrimeiro hit é miss; stale data possível
Read-ThroughCache é provider: app lê do cache, ele busca do DB automaticamenteCódigo limpoDepende de integração suportada
Write-ThroughApp escreve cache, cache escreve DB sincronamenteConsistência forteEscrita mais lenta; cache cresce com dados nunca lidos
Write-BehindApp escreve cache; cache escreve DB async em batchEscritas muito rápidasRisco de perda se cache falhar antes do flush
Refresh-AheadExpira itens quentes pró-ativamente antes do TTLHit rate altoComplexidade de previsão
python
# Cache-aside típico (Python + redis + RDS)
def get_user(user_id):
    key = f"user:{user_id}"
    cached = redis.get(key)
    if cached:
        return json.loads(cached)
    user = db.query("SELECT * FROM users WHERE id = %s", user_id)
    redis.setex(key, 300, json.dumps(user))  # TTL 5min
    return user

def update_user(user_id, data):
    db.execute("UPDATE users SET ... WHERE id = %s", user_id)
    redis.delete(f"user:{user_id}")   # invalidação explícita
💡
TTL é a chave: TTL curto = mais carga no DB mas menos stale; TTL longo = menos carga mas dados velhos. Regra prática: TTL = tolerância máxima a stale em ms. Para dados mutáveis, combine TTL com invalidação ativa em writes.

Escolha arquitetural — quando cada um ganha

📋 Sessão de usuário de e-commerce compartilhada entre múltiplas instâncias EC2

ElastiCache Redis (ou DynamoDB on-demand)

Session store requer acesso rápido de múltiplos hosts. Redis é tradicional. DynamoDB on-demand é alternativa serverless mais moderna.

Alt: Sticky sessions no ALBfunciona mas amarra usuário a 1 host e falha em failover.

📋 API pública com endpoints /produtos e /categorias acessados 10.000 req/s, dados mudam 1x/dia

CloudFront com TTL de horas + S3/ALB atrás

CDN absorve 99% dos requests na edge, origem quase nunca é tocada. Invalidação na atualização diária.

Alt: API Gateway com cachingfunciona mas fica em 1 região.

📋 Leaderboard de jogo — top 100 jogadores, atualizado a cada partida, consulta por tempo real

ElastiCache Redis com Sorted Sets

ZADD + ZREVRANGE resolve em uma chamada. Nem DynamoDB nem DAX oferecem sorted sets nativos.

Métricas críticas do ElastiCache (CloudWatch)

CacheHits / CacheMissesRatio < 0,8 sugere cache pequeno ou TTL mal calibrado.
EvictionsQualquer eviction significa pressão de memória — aumente node ou reduza dataset.
CPUUtilizationRedis single-thread → 100% no core principal significa CPU bound.
EngineCPUUtilizationMétrica mais precisa para Redis (ignora overhead do SO).
BytesUsedForCache / ReservedMemoryQuanto da memória está usado vs disponível.
CurrConnectionsAproximar do limite (65.000) é sinal de connection leak no cliente.

Q&A estilo exame

Quando usar DAX e quando usar ElastiCache na frente do DynamoDB?

DAX quando você quer solução gerenciada específica, compatibilidade total com a SDK do DynamoDB e quer evitar código de invalidação (write-through nativo). ElastiCache quando quer estruturas Redis (sorted sets, pub/sub) que DAX não oferece.

Como escolher entre cache-aside e write-through?

Cache-aside é o padrão default: simples, barato em cache memory. Write-through quando a aplicação NÃO pode ler dado stale (ex: financeiro). Combina com TTL para evitar cache “imortal”.

Redis Multi-AZ com auto-failover — RTO típico?

~30–60s. Failover elege nova primary automaticamente; DNS endpoint é atualizado. Cliente deve ter retry com backoff para absorver a janela de transição.

Aplicação começou a retornar dados antigos após deploy. Como diagnosticar?

Primeiro, verifique TTL e se houve mudança no schema (key format). Invalidação pode estar faltando. Se usar CloudFront, criar invalidation de /* (última medida). Em ElastiCache:FLUSHALL derruba tudo — use com cautela.
⚠️
Armadilhas:(1) Memcached não tem persistência — restart apaga tudo; (2) Redis single-thread, não adianta pegar node de 64 cores; (3) DAX só DynamoDB; (4) CloudFront invalidation custa após 1.000/mês; (5) Cache “thundering herd” — quando muitos clientes refazem cache ao mesmo tempo após expiração (mitigue com jitter no TTL).
Take-aways: cache é o multiplicador de performance mais barato. Escolha: Redis (rico), Memcached (simples), DAX (DynamoDB), CloudFront (HTTP). Padrão default: cache-aside com TTL. Monitore hit rate e evictions. Invalide em writes quando consistência importa.
🧩

Quiz rápido

3 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito