This document contains tips and best practices for caching in web applications. It discusses using HTTP caching to cache responses at the client-side or proxy level based on freshness and validation. It also covers caching fragments in Rails applications using the cache method, etagging, and Russian doll caching where child fragments are cached within parent cached fragments. The tips aim to reduce latency, bandwidth usage, and server response time through caching at different levels.
1 of 20
Download to read offline
More Related Content
Caching tips
1. Caching tips
Leo Soto M.
Continuum
Lecture & Beef, Marzo 2013
Sunday, March 3, 13
2. Caching tips
(for webapps)
Leo Soto M.
Continuum
Lecture & Beef, Marzoss 2013
Sunday, March 3, 13
3. “There are only
two hard things
in computer
science...
Sunday, March 3, 13
4. ...cache
invalidation and
naming things”
- Phil Karlton
Sunday, March 3, 13
7. VALIDATED CACHES
•HTTP/1.0:
Last-‐Modified
/
If-‐Modified-‐Since
304
Not
Modified
•HTTP/1.1:
ETag
/
If-‐None-‐Match
304
Not
Modified
Sunday, March 3, 13
8. CACHE INVALIDATION
•METODOS HTTP QUE INVALIDAN
CACHES FRESCAS:
POST
/resource
DELETE
/resource
PUT
/resource
Sunday, March 3, 13
9. EN RAILS
•FRESH CACHES:
expires_in
1.hour
•VALIDATED CACHES
if
stale?(etag:
@modelo)
otros_hits_a_la_bd
end
Sunday, March 3, 13
10. stale?(etag:
x)
-‐>
Etag:
md5(expand_cache_key(x))
# File activesupport/lib/active_support/cache.rb, line 77
def expand_cache_key(key, namespace = nil)
expanded_cache_key = namespace ? "#{namespace}/" : ""
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
expanded_cache_key << "#{prefix}/"
end
expanded_cache_key << retrieve_cache_key(key)
expanded_cache_key
end
# File activesupport/lib/active_support/cache.rb, line 90
def retrieve_cache_key(key)
case
when key.respond_to?(:cache_key) then key.cache_key
when key.is_a?(Array) then key.map { |element|
retrieve_cache_key(element)
}.to_param
else
end.to_s
end
Sunday, March 3, 13
11. # File activerecord/lib/active_record/integration.rb, line 37
def cache_key
case
when new_record?
"#{self.class.model_name.cache_key}/new"
when timestamp = self[:updated_at]
timestamp = timestamp.utc.to_s(:number)
"#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
else
"#{self.class.model_name.cache_key}/#{id}"
end
end
Sunday, March 3, 13
12. EN RAILS
•SIN ETAGGER
stale?(etag:
[current_user,
@modelo])
stale?(etag:
[current_user,
@otro])
stale?(etag:
[current_user,
@otromas])
Sunday, March 3, 13
13. EN RAILS
•CON ETAGGER
etag
{
current_user
}
stale?(etag:
modelo)
stale?(etag:
otro)
stale?(etag:
otromas)
Sunday, March 3, 13
14. EN RAILS
•EN AC PERFORACIONES
etag
{
[current_user,
ENV[‘COMMIT_HASH’]
}
stale?(etag:
modelo)
stale?(etag:
otro)
stale?(etag:
otromas)
Sunday, March 3, 13
15. Rails Fragment
Caching
-‐cache
‘foo’
do...end
-‐cache
modelo
do...end
-‐cache
[reporte,
‘inbox’]
do..end
# File actionpack/lib/action_controller/caching/fragments.rb, line 51
def fragment_cache_key(key)
ActiveSupport::Cache.expand_cache_key(
key.is_a?(Hash) ?
url_for(key).split("://").last :
key,
:views)
end
Sunday, March 3, 13
16. RUSSIAN DOLL
CACHING
-‐
cache
[reporte,
‘perforaciones’]
do
-‐
perforacion.each
do
|p|
-‐
cache
perforacion
do
%h1=
perforacion.titulo
%p=
perforacion.whatever
Sunday, March 3, 13
17. TIPS FRAGMENT
CACHING
•Aplicar a cosas que no
dependan del usuario actual
•Usar cache_digests +
memcached
Sunday, March 3, 13
18. CONCLUSIONES
•HTTP CACHING:
•CACHE LOCAL AL USUARIO
•AHORRA:
•LATENCIA
•ANCHO DE BANDA,
•TIEMPO DE RESPUESTA DEL
SERVIDOR
Sunday, March 3, 13
19. CONCLUSIONES
•FRAGMENT CACHING:
•CACHE GLOBAL DE LA APP
•AHORRA:
•HITS A LA BD
•CALCULOS
•RENDERING
Sunday, March 3, 13