Cache is a hardware or
software component that
stores data so future
requests for that data
can be served faster
- Wikipedia
Slide 5
Slide 5 text
There are only two
hard things in computer
science: cache invalidation
and naming things.
- Phil Karlton
Slide 6
Slide 6 text
Caching and RAM is the
answer to everything
- about Flickr Architecture
Slide 7
Slide 7 text
Cache é um dos
segredos da
escalabilidade e
boa performance
Slide 8
Slide 8 text
esta palestra é sobre
algumas práticas utilizadas
na globo.com e em
especial no Globo Play
Slide 9
Slide 9 text
Onde pode haver cache?
• navegador do usuário
• rede mundial de
computadores
• servidor da sua aplicação
Slide 10
Slide 10 text
navegador
cache no
Slide 11
Slide 11 text
Caching would be useless
if it did not significantly
improve performance
- HTTP/1.1 specification
Slide 12
Slide 12 text
Recursos necessários para
exibir uma página podem
ser reutilizados durante a
navegação
Slide 13
Slide 13 text
• documentos
• imagens
• scripts e folhas de estilo
• requisições assíncronas
O que pode ser cacheado?
por alguns minutos
por alguns meses
por alguns meses
por alguns minutos
Slide 14
Slide 14 text
Os cabeçalhos de resposta
do HTTP estabelecem
como e se o cache pode
ser feito
Slide 15
Slide 15 text
GET /main.css HTTP/1.1
Host: jcemer.com
Slide 16
Slide 16 text
GET /main.css HTTP/1.1
Host: jcemer.com
HTTP/1.1 200
Date: Tue, 13 Sep 2016 13:32:50 GMT
Cache-Control: max-age=604800
guarde por 7 dias!
Slide 17
Slide 17 text
permite que a resposta da
requisição seja
armazenada no cache
Cache-Control: max-age=604800
Cabeçalho de resposta
Slide 18
Slide 18 text
folha de estilo é
requisitada uma única vez
durante a navegação
Slide 19
Slide 19 text
Novas requisições são
disparadas quando o
recurso está expirado ou
o usuário força a
atualização da página
Slide 20
Slide 20 text
permitem adicionar mais
informações sobre o
recurso
Last-Modified: Mon, 12 Sep 2016 22:06:39 GMT
Etag: W/"337e7-8HrLmYe6UGIUDolQeGLoyw"
Cabeçalhos de resposta
Slide 21
Slide 21 text
GET /main.css HTTP/1.1
Host: jcemer.com
HTTP/1.1 200 OK
Date: Tue, 13 Sep 2016 13:32:50 GMT
Last-Modified: Mon, 12 Sep 2016 15:23:17 GMT
Cache-Control: max-age=604800
informação nova
Slide 22
Slide 22 text
permitem reaproveitar o
recurso caso a cópia em
cache ainda seja válida
If-Modified-Since: Mon, 12 Sep 2016 15:23:17 GMT
If-Match: W/"337e7-8HrLmYe6UGIUDolQeGLoyw"
Cabeçalhos de requisição
Práticas como esta
modificam completamente
a experiência do usuário
Slide 26
Slide 26 text
rede
cache na
Slide 27
Slide 27 text
Content delivery network
(CDN) is a globally
distributed network
of proxy servers
- Wikipedia
Slide 28
Slide 28 text
permite dar liberdade para
servidores de cache
intermediários
Cache-control: public
Slide 29
Slide 29 text
Documentação de como fazer
cache dos vídeos da globo.com
https://github.com/globocom/Globo-Live-Cache
Slide 30
Slide 30 text
Documentação de como fazer
cache dos vídeos da globo.com
TL;DR
respeite os cabeçalhos
das respostas
https://github.com/globocom/Globo-Live-Cache
Slide 31
Slide 31 text
servidor
cache no
Slide 32
Slide 32 text
cache server
Slide 33
Slide 33 text
O servidor de cache
intermedia a comunicação
com a aplicação ou
demais servidores
Slide 34
Slide 34 text
• imagens
• scripts e folhas de estilo
• documentos comuns a
todos os usuários
O que pode ser cacheado?
por alguns meses
por alguns meses
por alguns minutos
Os cabeçalhos das
respostas definem os
tempos de cache assim
como em um navegador
Slide 42
Slide 42 text
t1
t2
t1
requisições em
tempos diferentes
Slide 43
Slide 43 text
t1
t1
requisições em um
mesmo instante!
Slide 44
Slide 44 text
proxy_cache_lock on;
proxy_cache_lock_timeout 180;
apenas a primeira request
por determinado recurso
é encaminhada
Slide 45
Slide 45 text
t1
t1
t1
Slide 46
Slide 46 text
Requisições subsequentes
a um recurso ficarão
aguardando que o cache
seja atualizado
Slide 47
Slide 47 text
e caso minha rede
interna falhe?
Slide 48
Slide 48 text
proxy_cache_use_stale timeout error http_500;
permite entregar
conteúdo antigo caso
algum erro aconteça
Slide 49
Slide 49 text
No content
Slide 50
Slide 50 text
e caso minha
aplicação falhe?
Slide 51
Slide 51 text
proxy_cache_use_stale http_500;
permite entregar
conteúdo antigo caso a
aplicação retorne erro
Slide 52
Slide 52 text
No content
Slide 53
Slide 53 text
Esta prática pode garantir
que seu produto não caia
Slide 54
Slide 54 text
Cache é também
uma excelente
estratégia de
tolerância a falhas
Slide 55
Slide 55 text
proxy_cache_use_stale updating;
permite entregar
conteúdo antigo para
requisições subsequentes
Slide 56
Slide 56 text
Varnish e Squid possuem
estratégias melhores para
revalidar o cache sem
penalizar o usuário
http://serverfault.com/questions/576402/nginx-serving-stale-cache-
response-while-updating
Slide 57
Slide 57 text
aplicação
cache na
Slide 58
Slide 58 text
Cache na aplicação é
utilizado para diminuir o
tempo de resposta de
determinadas operações
Slide 59
Slide 59 text
• computações complexas
• dados comuns a certas
requisições
O que pode ser cacheado?
Slide 60
Slide 60 text
def program
@program ||= Program.find(@program_id)
end
Video class
Slide 61
Slide 61 text
Memoization é a prática
de armazenar o resultado
de operações para evitar
futuras execuções
Slide 62
Slide 62 text
def program
@program = Program.find(program_id) unless
defined? @program
end
https://github.com/rails/rails/commit/
36253916b0b788d6ded56669d37c96ed05c92c5c
Video class
Slide 63
Slide 63 text
Memoization é ideal
para operações de
objetos instanciados
durante uma requisição
Slide 64
Slide 64 text
Memoization em objetos
instanciados durante uma
requisição possibilita
pouco reuso
Slide 65
Slide 65 text
$program = Program.find(program_id)
Slide 66
Slide 66 text
Objetos instanciados
uma única vez no ciclo
de vida da aplicação
servem como
in-memory cache
Slide 67
Slide 67 text
cache.fetch(program_id) do
Program.find(program_id)
end
http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html
ActiveSupport::Cache::Store
Slide 68
Slide 68 text
Resultados armazenados
em objetos vitalícios
necessitam de um
tempo de expiração
Redis suporta diferentes
políticas para gerir o
máximo espaço
consumido
Slide 84
Slide 84 text
noeviction
allkeys-lru
evict keys trying to remove the less recently
used keys first
volatile-lru
equals allkeys-lru but only among keys that
have an expire set
http://redis.io/topics/lru-cache
Slide 85
Slide 85 text
O uso de um serviço para
cache introduz um ponto
único de falha
Slide 86
Slide 86 text
redis
ativado
* gráfico do API gateway do Globo Play
Slide 87
Slide 87 text
Redis suporta tolerância
a falhas através de
persistência em disco,
replicação e sentinel
http://redis.io/topics/persistence
http://redis.io/topics/replication
http://redis.io/topics/sentinel
Slide 88
Slide 88 text
No content
Slide 89
Slide 89 text
Sharding pode escalar o
cache horizontalmente e
melhorar a tolerância a
falhas
https://github.com/twitter/twemproxy
Diversas instâncias da
aplicação poderão tentar
revalidar o resultado
ao mesmo tempo
Slide 95
Slide 95 text
dado expirado
no cache!
Slide 96
Slide 96 text
cache.fetch(key, race_condition_ttl: 10.seconds) do
heavy_db_computation
end
http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html
ActiveSupport::Cache::Store
Slide 97
Slide 97 text
race_condition_ttl
revalida o cache editando
o valor armazenado
Slide 98
Slide 98 text
race_condition_ttl
revalida o cache editando
o valor armazenado
mas a leitura e escrita
não é transacional!
Slide 99
Slide 99 text
No content
Slide 100
Slide 100 text
Solução #1
Utilizar algum artifício de
query cache no próprio
banco de dados
Slide 101
Slide 101 text
Solução #2
Manter o cache sempre
válido com a ajuda de um
worker
Slide 102
Slide 102 text
Solução #3
Reescrever toda sua
aplicação em Elixir
Slide 103
Slide 103 text
Solução #4
Criar um micro-serviço
para esta operação crítica
protegido por um
servidor de cache
Slide 104
Slide 104 text
No content
Slide 105
Slide 105 text
nginx pode ser um ótimo
aliado para proteger
serviços internos