Estratégias de cachê
1) Para quê cajar e onde fazê-lo
Kesh é uma camada de memória rápida que reduz a latência e a pressão sobre recursos caros (CPU/BD/API externa). Objetivos importantes:- Velocidade (p95/p99 abaixo), custo (menos egress/CPU), estabilidade (menos dependências sob o pico).
- Suavizar os picos e isolar os «vizinhos barulhentos».
1. Cliente (navegador/celular) - HTTP-kesh, IndexedDB, armazenamento local.
2. Edge/CDN - Os nódulos POP estão mais próximos do usuário, armazenando a estática e parte da API.
3. L7-Passarela/Reverse-proxy - Nginx/Envoy/Varnish.
4. O dinheiro de serviço é Redis/Memcached dentro do cluster.
5. Intraprocessado - in-memory (Cafeine/Guava/LRU-map).
6. Dinheiro em BD - representações materiais, índices secundários.
Regra: Acerte o mais perto possível do consumidor, mas mantenha a verdade unicamente.
2) Pattern de cajado
2. 1 Cache-aside (“lazy loading”)
O aplicativo é lido primeiro a partir do cachê; ao falhar, da fonte, depois escreve para o dinheiro.
Os benefícios são simplicidade, controle. Contras: lançamentos frios, janelas de alinhamento.
2. 2 Read-through
A leitura é sempre feita através de um cachê que vai para a origem quando falha (biblioteca/camada de proxy).
É conveniente centralizar políticas TTL/serilização.
2. 3 Write-through / Write-back (write-behind)
Write-through: gravação em dinheiro e origem sincronizada → coerência superior, latência superior.
Write-back: gravação em dinheiro, entrada em flash asincrona na origem → rapidamente, mas riscos de perdas e conflitos.
2. 4 Refresh-ahead (proactive)
Prevê «TTL em breve» e atualiza a chave no fundo, impedindo o estampede.
2. 5 Negative caching
O cachê «sem dados/404/vazio» para um TTL curto reduz a pressão sobre a fonte.
2. 6 Micro-caching
Muito curtos TTL (0. 5-5 c) em L7 para «quase dinâmica» (lista, principal) - reduz drasticamente as caudas.
3) kesh HTTP: cabeçalhos e controle
3. 1 Cabeçalhos básicos
`Cache-Control`: `max-age`, `s-maxage` (для shared кэшей), `public/private`, `no-store`, `stale-while-revalidate`, `stale-if-error`.
Validadores: 'ETag' (hash de conteúdo), 'Last-Modificed'.
Solicitações de termos: 'If-None-Match', 'If-Modificed-Since' → 304 Not Modificed.
3. 2 Vary e chaves
'Vary: Aceitt-Encoding, Autorization, Cookie, Aceitt-Language' - forma diferentes opções de cachê. Minimize 'Vary' para não «explodir» a cardealidade.
3. 3 Exemplo de resposta HTTP
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60
ETag: "a1b2c3"
Vary: Accept-Encoding
4) Design de chaves e TTL
4. 1 Chaves
Estruture «tenant: user: SE): profile: v3» (inclua a versão do esquema).
Evite PII na chave.
Para coleções, chave + opções de consulta (normalizadas e ordenadas).
4. 2 TTL e coerência
O TTL curto reduz a concordância, mas aumenta as falhas.
Para os dados críticos, validadores ('ETag') e SWR (stale-while-revalidate).
Para os que raramente mudam, há um longo TTL + bombas de deficiência.
4. 3 Versioning/basting
Em caso de alterações incompatíveis - Altere o prefixo/versão da chave ('v2 → v3').
Para recursos estáticos - conteúdo hash no nome do arquivo.
5) Deficiência: estratégias e práticas
5. 1 Remoção direta
'DEL key '/' PURGE' no proxy. Perigo: corridas entre remoção e leitores múltiplos.
5. 2 Marcas/Surrogate keys
Vincule o documento a um conjunto de marcas de formatação (categoria/autor). Deficiência por formatação.
В Varnish/Edge — `Surrogate-Key: article:42 tag:author:7` + `BAN tag:author:7`.
5. 3 Event-driven deficiência
Pub/Sub (Kafka/NATS): Ao alterar a origem, publicamos o evento «invalidate».
Os consórcios do cachê ouvem e removem/atualizam as chaves.
5. 4 Bifaz
Primeiro marcamos a chave obsoleta (soft TTL), atendemos stale, atualizamos e substituímos atômicamente.
6) Luta contra estampede/dogpile e chaves quentes
6. 1 Request coalescing (singleflight)
Um produtor atualiza a chave, os outros aguardam o resultado (a editora «atualiza»).
6. 2 Jitter к TTL
Adicione o acidente (£10-20%) à TTL para evitar o apagão sincronizado.
6. 3 Soft-TTL + hard-TTL
Antes da soft-TTL é mantido a partir do cachê, paralelamente ao desencadeamento refresh; por hard-TTL, achamos que é uma falha.
6. 4 Chaves quentes
Os cachês locais estão acima do total (two-tier).
Replica a chave quente em vários chardes e escolha random (somente para read-only).
Rate limit para atualização de uma chave específica.
6. 5 Exemplo de Redis + Lua (desenho singleflight)
lua
-- SETNX lock with TTL to avoid deadlocks local ok = redis. call("SET", KEYS[1], "1", "NX", "EX", ARGV[1])
if ok then return "LOCKED"
else return "WAIT"
end
7) Políticas de exclusão e entrada em dinheiro
7. 1 Eviction
LRU: Simples e bom para a localidade.
LFU: Melhor com chaves quentes de longa vida.
ARC/TinyLFU: balanço recency/frequency.
7. 2 Admissão (entrada)
Não deixe entrar objetos raros gigantes (TinyLFU/Bloom Filtrs).
Compressão de grandes valores (LZ4/Zstd) no limite de tamanho/latência.
8) Charding e topologia
8. 1 Consistent hashing
Distribui as chaves de forma estável em nódulos, reduzindo os movimentos de crescimento/compressão do cluster.
8. 2 Topologias Redis/Memcached
Redis Cluster (slots/chards), Sentinel (feelover), replicação read-only.
O Memcached é um cliente-site charding (ketama hasing), sem replicação ao nível do servidor.
8. 3 Local + distribuído
Cascata: in-proc (micro-TTL/LRU) → Redis (TTL mais longo) → origem.
Cuidado com os dois pontos TTL e validadores de dinheiro.
9) Edge, CDN e L7-kesh
9. 1 Micro-cache на Nginx
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m inactive=10m;
map $request_method $skip_cache { default 0; POST 1; PUT 1; DELETE 1; }
server {
location /api/list {
if ($skip_cache) { add_header Cache-Control "no-store"; }
proxy_cache api;
proxy_cache_valid 200 2s; # micro-cache proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on; # SWR add_header X-Cache $upstream_cache_status;
proxy_pass http://upstream;
}
}
9. 2 Envoy (SWR e condições)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. http. cache. file_system_http_cache. v3. FileSystemHttpCacheConfig cache_path: "/var/cache/envoy"
9. 3 Varnish (Surrogate keys)
Use «Surrogate-Key» e «ban» por marcas de formatação.
10) Kesh e coerência de dados
10. 1 Read-your-writes
Para os perfis/cestas personalizados, forneça TTL curtos ou escreva através do dinheiro (write-through) ou marca o cliente (bypass por N segundos após a gravação).
10. 2 Eventual vs Strong
Para recomendação/análise - eventual + TTL longo.
Para dinheiro/estado de encomendas - TTL curto, validação, às vezes sem cachê nas vias críticas.
10. 3 Invariantes
Não deixe cair os campos que afetam a segurança/LCA sem TTL rigoroso ou reexaminação.
11) Observabilidade, SLO e controle
11. 1 Métricas
hit_ratio (общий и per-route), byte_hit_ratio, miss_rate.
stampede_prevented_total, refresh_ahead_total, ban/purge_total.
Latência: p50/p95/p99 do cachê vs da fonte.
hot_keys_topN e seus QPS/bytes.
11. 2 Logs e traçados
Logue 'X-Cache: HIT/MISS/STALE/UPDATING'.
Nos trailers, assinale a origem da resposta ('cachê = true', 'tier = edge' service 'local').
11. 3 abordagem SLO
Exemplo: "para API/catalog p99 ≤ 250 ms, cachê hit ≥ 85%, estampede ≤ 0. 1% de solicitações".
11. 4 Runbooks
«Falhas crescem» → verificar TTL, aquecimento/deficiência, hot-keys, tamanho do cachê e política de aceitação.
12) Segurança e multi-tenência
Insira o tênant-id nas chaves (e em 'Vary' no HTTP).
Não acerte respostas privadas como 'público'.
Criptografe o dinheiro com dados sensíveis ou guarde apenas não-PII/ID.
13) Receitas típicas
13. 1 Catálogo/fita (quase dinâmica)
Edge-microceque 1-3 com + SWR, interior - Redis para 15-60 s, deficiência para eventos de atualização.
13. 2 Perfil do usuário
Cachê-aside com TTL 30-120 s, bypass 5-10 s após a atualização do perfil (cookie/heder), ou write-through.
13. 3 Cursos/guias de câmbio
TTL longo (minutos-relógio) + deficiente alvo ao publicar novos dados; 'ETag' para GET condicional.
13. 4 Entrega de busca
Edge-microcexto 1-2 com, dentro - refresh-ahead e coalescing, normalização dos parâmetros query na chave.
14) Anti-pattern
A única esperança em TTL → longas janelas de irrelevância.
Gigantesco 'Vary': «explosão» de opções → baixo hit-rate.
Um único cachê para prod/experiments → poluição.
Não há proteção contra estampede → picos na origem quando o TTL terminar.
Dinheiro em dinheiro/direitos/LCA sem garantias rigorosas.
Compressão «tudo» - CPU extra, deterioração p99 em pequenos objetos.
15) Folha de cheque de implementação
- Defina os níveis de caju e seus alvos (edge/service/local).
- Projete as chaves (versionização, tenant, normalização de parâmetros).
- Selecione o pattern (cachê-aside/read-through/refresh-ahead).
- Configure o TTL/soft-TTL/jitter e inclua o SWR.
- Implemente coalescing/singleflight, proteja contra estampede.
- Organize a deficiência (eventos, tags, purge/ban).
- Digite as métricas hit-ratio/latência e dashboard 'X-Cachê'.
- Faça testes de carga com chaves quentes.
- Sugira SLO e runbooks.
- Verifique a segurança/isolamento tenant e 'Vary'.
16) FAQ
Q: O que escolher é cachê-aside ou read-through?
A: Para serviços simples - cachê-aside. É preciso centralização e uma política unificada - read-through.
Q: Como compreender a TTL ideal?
A: Afaste a obsolescência permitida, a frequência de atualizações e o hit-rate de destino; adicione o jitter e observe p95/r99/valor.
Q: Quando é apropriado write-back?
A: Para os fluxos altamente comprimidos, onde a consistência eventual é aceitável e há uma fila/logos confiáveis para «terminar».
Q: Pode-se acenar as respostas autorizadas?
A: Sim, mas assinale «private» e/ou inclua tenant/user na chave/« Vary ». Para truly-private, o console do cliente.
Como aquecer o dinheiro?
A: Listas de chaves populares, background wormer, repique de logs, aquecimento antes do lançamento/pico (Black Friday etc.).
17) Resultados
O acervo eficiente é o design de chaves + TTL + razoavelmente selecionado por pattern, reforçado por deficiência de evento, SWR/refresh-ahead e proteção contra estampede. Espalhe o dinheiro por nível (cliente/edge/serviço), adicione observabilidade e SLO - e obtenha caudas de latência estáveis, custo previsível e resistência às cargas de pico.