$30 off During Our Annual Pro Sale. View Details »

Cache em aplicações web

Cache em aplicações web

Há uma famosa frase que dita ser invalidação de cache uma das mais difícil tarefas da Ciências da Computação. Esta palestra traz diferentes abordagens para armazenar dados em cache para aplicações Web. Tecnologias como HTTP, NGINX, Redis, cache em memória entre outras serão analisadas juntamente com algumas práticas para endereçar cache em diferentes lev

Jean Carlo Emer

September 24, 2016
Tweet

More Decks by Jean Carlo Emer

Other Decks in Technology

Transcript

  1. em aplicações
    web
    cache
    @jcemer

    View Slide

  2. jcemer.com
    twitter.com/jcemer

    View Slide

  3. globo.com
    talentos.globo.com

    View Slide

  4. Cache is a hardware or
    software component that
    stores data so future
    requests for that data
    can be served faster
    - Wikipedia

    View Slide

  5. There are only two 

    hard things in computer
    science: cache invalidation
    and naming things.
    - Phil Karlton

    View Slide

  6. Caching and RAM is the
    answer to everything
    - about Flickr Architecture

    View Slide

  7. Cache é um dos
    segredos da
    escalabilidade e
    boa performance

    View Slide

  8. esta palestra é sobre
    algumas práticas utilizadas
    na globo.com e em
    especial no Globo Play

    View Slide

  9. Onde pode haver cache?
    • navegador do usuário
    • rede mundial de
    computadores
    • servidor da sua aplicação

    View Slide

  10. navegador
    cache no

    View Slide

  11. Caching would be useless
    if it did not significantly
    improve performance
    - HTTP/1.1 specification

    View Slide

  12. Recursos necessários para
    exibir uma página podem
    ser reutilizados durante a
    navegação

    View Slide

  13. • 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

    View Slide

  14. Os cabeçalhos de resposta
    do HTTP estabelecem
    como e se o cache pode
    ser feito

    View Slide

  15. GET /main.css HTTP/1.1
    Host: jcemer.com

    View Slide

  16. 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!

    View Slide

  17. permite que a resposta da
    requisição seja
    armazenada no cache
    Cache-Control: max-age=604800
    Cabeçalho de resposta

    View Slide

  18. folha de estilo é
    requisitada uma única vez
    durante a navegação

    View Slide

  19. Novas requisições são
    disparadas quando o
    recurso está expirado ou
    o usuário força a
    atualização da página

    View Slide

  20. 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

    View Slide

  21. 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

    View Slide

  22. 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

    View Slide

  23. GET /main.css HTTP/1.1
    Host: jcemer.com
    If-Modified-Since: Mon, 12 Sep 2016 15:23:17 GMT

    View Slide

  24. GET /main.css HTTP/1.1
    Host: jcemer.com
    If-Modified-Since: Mon, 12 Sep 2016 15:23:17 GMT
    HTTP/1.1 304 Not Modified
    Date: Tue, 13 Sep 2016 13:32:50 GMT
    Last-Modified: Mon, 12 Sep 2016 15:23:17 GMT
    Cache-Control: max-age=604800

    View Slide

  25. Práticas como esta
    modificam completamente
    a experiência do usuário

    View Slide

  26. rede
    cache na

    View Slide

  27. Content delivery network
    (CDN) is a globally
    distributed network 

    of proxy servers
    - Wikipedia

    View Slide

  28. permite dar liberdade para
    servidores de cache
    intermediários
    Cache-control: public

    View Slide

  29. Documentação de como fazer
    cache dos vídeos da globo.com
    https://github.com/globocom/Globo-Live-Cache

    View Slide

  30. 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

    View Slide

  31. servidor
    cache no

    View Slide

  32. cache server

    View Slide

  33. O servidor de cache
    intermedia a comunicação
    com a aplicação ou
    demais servidores

    View Slide

  34. • 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

    View Slide

  35. • Varnish
    • Squid
    • nginx
    Quais ferramentas existem?
    https://varnish-cache.org
    http://www.squid-cache.org
    https://www.nginx.com

    View Slide

  36. nginx pode operar como
    um proxy reverso e
    como cache

    View Slide

  37. location / {
    proxy_pass http://otherserver;
    }
    todas as requisições são
    repassadas para outro
    servidor

    View Slide

  38. View Slide

  39. proxy_cache_path /path/to/cache;

    location / {
    proxy_pass http://otherserver;
    proxy_cache cache;
    }
    caching ativado!

    View Slide

  40. View Slide

  41. Os cabeçalhos das
    respostas definem os
    tempos de cache assim
    como em um navegador

    View Slide

  42. t1
    t2
    t1
    requisições em
    tempos diferentes

    View Slide

  43. t1
    t1
    requisições em um
    mesmo instante!

    View Slide

  44. proxy_cache_lock on;
    proxy_cache_lock_timeout 180;
    apenas a primeira request
    por determinado recurso
    é encaminhada

    View Slide

  45. t1
    t1
    t1

    View Slide

  46. Requisições subsequentes
    a um recurso ficarão
    aguardando que o cache
    seja atualizado

    View Slide


  47. e caso minha rede
    interna falhe?

    View Slide

  48. proxy_cache_use_stale timeout error http_500;
    permite entregar
    conteúdo antigo caso
    algum erro aconteça

    View Slide

  49. View Slide

  50. e caso minha
    aplicação falhe?

    View Slide

  51. proxy_cache_use_stale http_500;
    permite entregar
    conteúdo antigo caso a
    aplicação retorne erro

    View Slide

  52. View Slide

  53. Esta prática pode garantir
    que seu produto não caia

    View Slide

  54. Cache é também
    uma excelente
    estratégia de
    tolerância a falhas

    View Slide

  55. proxy_cache_use_stale updating;
    permite entregar
    conteúdo antigo para
    requisições subsequentes

    View Slide

  56. 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

    View Slide

  57. aplicação
    cache na

    View Slide

  58. Cache na aplicação é
    utilizado para diminuir o
    tempo de resposta de
    determinadas operações

    View Slide

  59. • computações complexas
    • dados comuns a certas
    requisições
    O que pode ser cacheado?

    View Slide

  60. def program
    @program ||= Program.find(@program_id)
    end
    Video class

    View Slide

  61. Memoization é a prática
    de armazenar o resultado
    de operações para evitar
    futuras execuções

    View Slide

  62. def program
    @program = Program.find(program_id) unless 

    defined? @program
    end
    https://github.com/rails/rails/commit/
    36253916b0b788d6ded56669d37c96ed05c92c5c
    Video class

    View Slide

  63. Memoization é ideal
    para operações de
    objetos instanciados
    durante uma requisição

    View Slide

  64. Memoization em objetos
    instanciados durante uma
    requisição possibilita 

    pouco reuso

    View Slide

  65. $program = Program.find(program_id)

    View Slide

  66. Objetos instanciados
    uma única vez no ciclo
    de vida da aplicação
    servem como 

    in-memory cache

    View Slide

  67. cache.fetch(program_id) do
    Program.find(program_id)
    end
    http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html
    ActiveSupport::Cache::Store

    View Slide

  68. Resultados armazenados
    em objetos vitalícios
    necessitam de um 

    tempo de expiração

    View Slide

  69. cache.write(key, value, expires_in: 1.minute)
    http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html
    ActiveSupport::Cache::Store

    View Slide

  70. node-cache
    https://github.com/ptarjan/node-cache
    cache.put(key, value, 6000)

    View Slide

  71. Toda aplicação possui um
    limite prático de memória

    View Slide

  72. https://github.com/ptarjan/node-cache/issues/77

    node-cache: projeto com 540 stars

    View Slide

  73. View Slide

  74. when the cache exceeds
    the allotted size, a cleanup
    will occur which tries to
    prune the cache down
    ActiveSupport::Cache::
    MemoryStore

    View Slide

  75. A moda agora é escalar
    horizontalmente as
    aplicações em diversos
    containers

    View Slide

  76. View Slide

  77. View Slide

  78. https://tsuru.io

    View Slide

  79. Never assumes that
    anything cached in
    memory or on disk
    will be available on 

    a future request
    https://12factor.net/processes

    View Slide

  80. Uma storage cache-valor
    pode servir como cache
    para seus containers

    View Slide

  81. • Redis
    • Memcached
    Quais storages chave
    +valor existem?
    http://redis.io
    http://memcached.org

    View Slide

  82. http://redis.io

    gem redis-store

    View Slide

  83. Redis suporta diferentes
    políticas para gerir o
    máximo espaço
    consumido

    View Slide

  84. 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

    View Slide

  85. O uso de um serviço para
    cache introduz um ponto
    único de falha

    View Slide

  86. redis
    ativado
    * gráfico do API gateway do Globo Play

    View Slide

  87. 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

    View Slide

  88. View Slide

  89. Sharding pode escalar o
    cache horizontalmente e
    melhorar a tolerância a
    falhas
    https://github.com/twitter/twemproxy

    View Slide

  90. http://www.slideshare.net/ShashiShekarMadappa/evcache-at-netflix

    https://github.com/Netflix/EVCache

    View Slide

  91. http://www.slideshare.net/ShashiShekarMadappa/evcache-at-netflix

    https://github.com/Netflix/EVCache

    View Slide

  92. http://www.slideshare.net/ShashiShekarMadappa/evcache-at-netflix

    https://github.com/Netflix/EVCache

    View Slide

  93. https://www.youtube.com/watch?v=Rzdxgx3RC0Q

    View Slide

  94. Diversas instâncias da
    aplicação poderão tentar
    revalidar o resultado 

    ao mesmo tempo

    View Slide

  95. dado expirado 

    no cache!

    View Slide

  96. 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

    View Slide

  97. race_condition_ttl
    revalida o cache editando
    o valor armazenado

    View Slide

  98. race_condition_ttl
    revalida o cache editando
    o valor armazenado
    mas a leitura e escrita
    não é transacional!

    View Slide

  99. View Slide

  100. Solução #1
    Utilizar algum artifício de
    query cache no próprio
    banco de dados

    View Slide

  101. Solução #2
    Manter o cache sempre
    válido com a ajuda de um
    worker

    View Slide

  102. Solução #3
    Reescrever toda sua
    aplicação em Elixir

    View Slide

  103. Solução #4
    Criar um micro-serviço
    para esta operação crítica
    protegido por um
    servidor de cache

    View Slide

  104. View Slide

  105. nginx pode ser um ótimo
    aliado para proteger
    serviços internos

    View Slide

  106. https://github.com/plataformatec/faraday-http-cache

    View Slide

  107. Respeite os
    cabeçalhos HTTP
    #1

    View Slide

  108. Cache é
    assunto sério
    #2

    View Slide

  109. Monitore hit/miss
    e outras métricas
    da sua estratégia
    de cache
    #3

    View Slide

  110. Pondere bem antes
    de escolher uma
    estratégia de cache
    #4

    View Slide

  111. foi um prazer
    obrigado
    @jcemer

    View Slide