Caching/Expiring in Rails

35
Caching With Rails By Carmen Diaz Echauri – [email protected] For www.blazingcloud.net Rails version 2.3.8

description

Caching & Expiring in Rails

Transcript of Caching/Expiring in Rails

Page 1: Caching/Expiring in Rails

Caching  With  Rails  

By  Carmen  Diaz  Echauri  –  [email protected]  For  www.blazingcloud.net  

Rails  version  2.3.8  

Page 2: Caching/Expiring in Rails

Caching  with  Rails  

Scaling  your  Applica

Fons  

•  Rails  provides  by  default  three  techniques:  –   Page  Caching    –   AcFon  Caching  – Fragment  Caching  

Page 3: Caching/Expiring in Rails

Page  Caching  

•  Allows  the  request  for  a  generated  page  to  be  fulfilled  by  the  webserver,  without  ever  having  to  go  through  your  Rails  applicaFon.  

Client   Apache   Mongrel  

Public/users.html  

hOp://localhost:3000/users  

Page 4: Caching/Expiring in Rails

Page  Caching  

 Next  Fme  we  request  the  same  page,  apache  will  load  the  page  from  the  filesystem  and  send  it  back  to  the  client.  

Client   Apache   Mongrel  

Public/users.html  hOp://localhost:3000/users  

Page 5: Caching/Expiring in Rails

When  we  might  want  to  page  cached?  

•  When  every  user  always  sees  exactly  the  same  content  on  a  page,  even  if  they  are  login  to  the  admin  interface  or  not.  But  It's  always  the  same.  

•  It  doesn't  change  so  oWen.  Maybe  once  per  day,  week  or  month.  

Page 6: Caching/Expiring in Rails

Get  started  with  caching….  

•  Make  sure  config.acFon_controller.perform_caching  is  set  to  true  for  your  environment.  (config/environments/development.rb)  

config.acFon_controller.perform_caching  =  true  

Page 7: Caching/Expiring in Rails

Page  Caching  

Page 8: Caching/Expiring in Rails

Page  Caching  OpFons  

•  format.json  {render  :json  =>  @users}  

•  format.iphone  –  /config/iniFalizers/mime_types.rb  

•  Mime::Type.register_alias  “text/html”,  :iphone  –  /app/views/users/index.iphone.erb  

/public/users.html  /public/users.xml  /public/users.json  /public/users.iphone  

Page 9: Caching/Expiring in Rails

Caching  locaFon  /config/environment.rb  

versus  

Page 10: Caching/Expiring in Rails

Page  caching  

•  Page  caching  ignores  all  parameters  – hOp://localhost:3000/users?page=1  Will  be  wriOen  out    

so  if  someone  request  hOp://localhost:3000/users?page=3  it  will  be  gegng  users.html.  

Page 11: Caching/Expiring in Rails

AcFon  Caching  

•  Caching  stored    – Page  Caching  

•  Stored  on  Disk  – AcFon  &  Fragment  Caching  

•  Use  the  configured  cache  that  we  configure  in  our  rails  instance.    

Page 12: Caching/Expiring in Rails

When  to  do  AcFon  Caching?    •  When  we  need  filters  to  run  – Like  authenFcaFon    

Client   Apache   Mongrel  

Public/posts.html  

hOp://localhost:3000/posts  

Run  Filters  (authenFcate)  

Page 13: Caching/Expiring in Rails

AcFon  Caching  

Page 14: Caching/Expiring in Rails

AcFon  Caching  

Didn’t  call  the  acFon.  It  loaded  straight  out  of  the  cache  

It  executed  the  acFon  

Page 15: Caching/Expiring in Rails

AcFon  Caching  OpFons  

/config/environments/development.rb  

•  config.cache_store  =  :file_store,  'tmp/cache’  

   (AcFveSupport::Cache::FileStore)    

•  config.cache_store  =  :memory_store  

 (AcFveSupport::Cache::MemoryStore)    

–  {}  in  memory  –background-­‐.  But  you  can  run  out  of  memory  –  No  sharing  between  processes.  You  cannot  use  it  if  you  run  more  than  

one  instance  of  your  rails  apps.    

Page 16: Caching/Expiring in Rails

AcFon  Caching  OpFons….  

•  config.cache_store  =  :mem_cache_store  

•  config.cache_store  =  :mem_cache_store,  :namespace  =>  “store”    (share  apps)  

•  config.cache_store  =  :mem_cache_store,  192.168.1.255:1001,  192.168.1.255:1002  (mulFple  servers)  

 (AcFveSupport::Cache::MemCacheStore)    •  config.cache_store  =  :drb_store  

(AcFveSupport::Cache::DRbStore)    •  config.cache_store  =  :custom_store  

Page 17: Caching/Expiring in Rails

AcFon  Caching    •  Features  

–  Cached  the  acFon  without  the  layout.  

it  will  only  cache  your  acFon  content.  So,  if  you  need  some  sort  of  data  you  might  want  to  use  before_filter  and  set  you  instance  variable      

Page 18: Caching/Expiring in Rails
Page 19: Caching/Expiring in Rails

AcFon  Caching    

•  Features  (cont)  •  CondiFonal  AcFon  acFon  using  :if  (or  :unless)  =>  Proc.new{….}  to  

specify  when  the  acFon  should  be  cached.    

•  Specific  path  using  :cache_path  =>  Proc.new  {  |controller|  or  :cache_path  =>  <method>  

:expires_in  =>1.hour  to  specify  when  the  acFon  should  be  cached.      

(only  with  memcached  &  rails  >  2.1)  

Page 20: Caching/Expiring in Rails

Fragment  Caching  •  Is  useful  for  dynamic  web  applicaFons  •  Allows  you  to  fragment  many  pieces  of  the  view.  The  pieces  will  be  wrapped  in  a  cache  block  and  served  out  of  the  cache  store  when  the  next  request  comes  in.    

Client   Apache   Mongrel  

header  

hOp://localhost:3000/users  body  

widgets  

Page 21: Caching/Expiring in Rails

Fragment  Caching    To  implement  fragment  caching,  you  cache  your  method    in  the  view.  

All  keys  are  prefixed  with  "views/"  

Page 22: Caching/Expiring in Rails

Fragment  Caching  

You  can  create  your  own  key:  <%  cache("#{@user.id}-­‐recents_joined")  do  %>  or  use  the  rails  way    

<%  cache([user,  post,  “toolbar”])  do  %>  

Page 23: Caching/Expiring in Rails

Memcached  

•  Is  a  hash  in  memory,    key-­‐value  store    {}  in  memory  

(LiveJournal)    –  To  implement  /config/environments/producFon.rb  

config.cache_store  =  :mem_cache_store  Same  thing  as  config.cache_store  =  :memory_store    

but  it  runs  as  a  separate  process.  You  can  have  several  rails  

instances  that  references  the  same  mencached  instance    -­‐  Note:  make  sure  to  install  the  gem  memcached-­‐client.  

Page 24: Caching/Expiring in Rails

Memcached  uses    •  Fragment  Cache  Store  

•  AcFon  &  Fragment  Caching  

Page 25: Caching/Expiring in Rails

Memcached  uses    

•  As  an  Object  Store  –  Rails.cache.read  –  Rails.cache.write  –  Rails.cache.fetch  –  Rails.cache.delete  –  Rails.cache.exists?  –  Rails.cache.clear  –  Rails.cache.increment  –  Rails.cache.clear  

Page 26: Caching/Expiring in Rails

Memcached  uses    

Page 27: Caching/Expiring in Rails

Memcached  ….  Some  points:  -­‐  Expire  at  def  self.recent      Rails.cache.fetch("recent_posts",  :expires_in  =>  30.minutes)  do          self.find(:all,  :limit  =>  10)    end  

end  Run  this  query  every  30  minutes…    

-­‐    You  don’t  need  to  have  memcached  installed  to  develop  locally    You  will  get  MemCacheError  (No  connecFon  to  server):  No  connecFon  to  server  Cache  miss:    But,  your  app  will  work  just  fine.  Rails  will  always  execute  the  contents  of  the  fetch  blocks,  and  will  return  nil  for  any  reads.  

Page 28: Caching/Expiring in Rails

Expiring  cached  pages  One’s  first  inclinaFon  may  be  to  expire  pages  in  the  Controller  and  usually  via  the  update  method.    Depending  on  which  technique  you  choose  to  expire  pages  you  can  use  the  method  expire_page  {acFon,fragment}  

Instead  of  having  expire  methods  around  your  controllers,  to  clear  cache  files  based  on  when  a  model  is  updated,  sweepers  are  the  way  to  go.  

Page 29: Caching/Expiring in Rails

Expiring  cached  page  AcFonController::Caching::Sweeper  class.  (Share  Objects)    

–  Can  observe  Controllers  –  Can  observe  Models  

Hooks:  Any  observer  callbacks  

 aWer  create  

 aWer  destroy    aWer_save,  etc.  

Also  in  any  controllers  callbacks  •  before/aWer_<controller_name>  

•  before/aWer_<controller_name>_<acFon>  

Page 30: Caching/Expiring in Rails

Expiring  cached  page  To  implement  sweepers:  

 Declare  a  new  load  path  in  /config/environment.rb  to  keep  the  sweepers  separate  from  models  and  controllers.  

config.load_paths  <<  "#{RAILS_ROOT}/app/sweepers”  

Create  the  folder  and  the  observer  files  

Page 31: Caching/Expiring in Rails

Expiring  cached  page  

And  then  we  will  tell  the  controller  to  use  the  sweeper  

cache_sweeper  :user_sweeper,  :only  =>  [:create,  :update,  :destroy]  

When  to  call  the  method  

Observe  the  model  

Page 32: Caching/Expiring in Rails

Expiring  cached  page  

Page 33: Caching/Expiring in Rails

Another  way  to  expire.  Clearing  the  cache  

And  you  could  use  it  in  a  cron  call…  

Page 34: Caching/Expiring in Rails

Some  thoughts    ImplemenFng  page  caching  can  be  easy.  However,  expiring  can  be  prove  to  be  a  bit  more  challenging  .  

•  I  find  tesFng  kind  of  tricky.  •  I  read  through  numerous  blog  posts  but    I  couldn’t    quite  figure  out  

how  to  get  things  to  work  as  I  hoped.    •  The  following  are  alternaFves  I’ve  recently  used:    

–  Custom  Macthers  by  overwriFng  the  matches?  method  •  AcFonController::Caching::AcFons    

–   Build  your  CachePage  /  Fragment  Page  class  and  use    •  AcFonController::Base.expire_page(    )  •  AcFonController::Caching::Fragments  

–  expire_fragment  –  fragment_cache_key  –  fragment_exist?  –  read_fragment  –  write_fragment  

Page 35: Caching/Expiring in Rails