rails caching

13
Vincent Spehner Twitter: @vzmind Blog: vzmind.tumblr.com Caching with Rails Janvier 2011

Upload: vzmind-itself

Post on 06-May-2015

2.026 views

Category:

Technology


7 download

DESCRIPTION

A brief overview of caching technics using Rails

TRANSCRIPT

Page 1: Rails caching

Vincent SpehnerTwitter: @vzmindBlog: vzmind.tumblr.com

Caching with Rails

Janvier 2011

Page 2: Rails caching

Vzmind aka Ruby on Rails creator

Page 3: Rails caching

Almost 20 000 Vidéos

2 000 000 pages viewed

https://github.com/thinkdry/blank-application

Why caching ?Culture Pub

Page 4: Rails caching

Cache is everywhere• Almost at each step beetween the request and the data itself, a cache can be added

• Rails caching keyworld:• Pages • Action• Fragment• Sweepers

Proxy(Squid,

Varnish)

Web Server(Apache,

Nginx)

Rails Stack

(Rack, App)

DB (PostgreSQL,

MySQL)Browser

Cache as earlier as you can

config.action_controller.perform_caching = true

app/config/environments/production.rb

Page 5: Rails caching

Pages caching• Simpliest and most disconnected from Rails Cache

• Easy to implement but monotlithic and limited

• Stored inside the File System only

config.action_controller.page_cache_directory = RAILS_ROOT + “/…”config/environment.rb

class Articles < ContentController # Add cache on articles index page caches_page :index

app/controllers/articles_controller.rb

public/cache/articles.html

ProxyWeb Serve

r

Rails Stack DBBrow

ser

Page 6: Rails caching

Action caching• A bit flexible with parameters and path builder

• Easy to implement

• Careful with filters (Action caching is an around filter itself)

•Careful with cache path

• Choose your Cache Store

config.action_controller.cache_store = :file_store, RAILS_ROOT + /public/cache“config/environment.rb

class Articles < ContentController caches_action :show, :cache_path => Proc.new{ |controller| if controller.request.mobile_device? controller.params.merge(:mobile=>controller.request.mobile_device?) else controller.params end}

app/controllers/articles_controller.rb

expire_action :action => :showApp/sweepers/article_sweeper.rb

public/cache/articles.html

ProxyWeb Serve

r

Rails Stack DBBrow

ser

Page 7: Rails caching

Fragment caching

• Required for dynamic websites

• Atomic caching (result/string/object)

• Choose your Cache Store

- cache(:action => ‘list', :action_suffix => 'all_articles’) do = All articles: [email protected] do |article| = article.title

app/views/articles/index.haml.html

expire_fragment(:controller => ‘articles', :action => ‘list', :action_suffix => 'all_articles')

app/sweepers/article_sweeper.rb

public/cache/articles.html

ProxyWeb Serve

r

Rails Stack DBBrow

ser

Page 8: Rails caching

Overview of Cache Stores

• ActiveSupport::Cache::MemoryStore• Default memory storage• Store everything (even object)• Not thread safe

•ActiveSupport::Cache::FileStore• Just for my HTML output• Old school• Simple

• ActiveSupport::Cache::MemCacheStore• Most popular memory cache store• Multi servers• Time-based expiry support

Page 9: Rails caching

Keep a clean cache• Corrupted cache is dangerous

• Maintaining a cache is costly and add complexity • Time based flushing if using memcached

class ArticleSweeper < ActionController::Caching::Sweeper # This sweeper observe articles model and delete cache on save observe :article def after_save(article) clear_article_cache(article) end

def clear_article_cache(article) expire_page index_path, client endEnd

app/sweepers/article_sweeper.rb

Page 10: Rails caching

Bypass the Rails Stack

• Pages caching need you to serve the file « manually »

• Nginx/apache rewrite rules • Hack for subdomain if any

# Check index CACHE set $requested_page $request_uri;

# Initialize variables set $cache_path "/cache/views/$http_host/static/";

if ($request_uri ~ ^/$){ set $requested_page "index"; }

# Check if the page is in the cache. if (-f $document_root/$cache_path/$requested_page.html) { rewrite (.*) $cache_path/$requested_page.html break; }

Page 11: Rails caching

Who is caching?

• Classic caching ?

• Using Memcached ?

• Using Rack::Cache ?

• Never cached anything ?

Page 12: Rails caching

memcached Power

• Avoiding cache cleaning is possible !!

• :expire_in > 30.minutes

• Intelligent keys

- cache(“#{article.id}-#{article.update_at.to_i}” -data) do = My heavy stuffs to cache

# => /cache/3-1234567-data

#Or just writing- cache(article) do = My heavy stuffs to cache

# => /cache/articles/3-1234567

#And if related to a specific user- cache([article,user]) do = My heavy stuffs to cache

# => /cache/articles/3-1234567/users/23-12345678

Page 13: Rails caching

Thanks you folks !!