Speed Up with Rails Cache

Me

Big Problem

There are only two hard problems in Computer Science: cache invalidation and naming things. - Phil Karlton

Fortunately, Rails has made it perfect!

启用缓存

config.action_controller.perform_caching = true

核心:Rails.cache

Rails.cache.write 'foo', 'bar'

Rails.cache.read 'foo'

不存在则写,存在则读

Rails.cache.fetch 'a_big_data' do { (1..1000000).inject(:+) }

文件位置 ./tmp/cache

缓存原理

def body_html 
  Rails.cache.fetch "#{cache_key}/body_html" do
    render(body) 
  end
end

Caching Strategies

Fragment Caching

<%= cache @post do %>
  <p>
    <b>Title:</b>
    <%= @post.title %>
  </p>

  <p>
    <b>Content:</b>
    <%= @post.content %>
  </p>
<% end %>

手动设置过期

expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products')

Fragment Caching 效果

Fragment Caching key生成策略

cache 'explicit-key'      # views/explicit-key
cache @post               # views/posts/2-1283479827349
cache [@post, 'sidebar']  # views/posts/2-2348719328478/sidebar
cache [@post, @comment]   # views/posts/2-2384193284878/comments/1-2384971487
cache :hash => :of_things # views/localhost:3000/posts/2?hash_of_things

Action Caching

caches_action :index, :cache_path => proc {|c| { :tag => Post.maximum('updated_at') } }

Page Caching

caches_page :index

特点:

HTTP Caching

报文头:
Cache-Control: max-age=0, private, must-revalidate
示例:
def show
  @post = Post.find params[:id]

  if stale? @post, :etag => @post.posted_at do
    respond_with @post
  end
end
特点:

Tips

Thanks to

http://www.broadcastingadam.com/2012/07/advanced_caching_revised/

http://guides.rubyonrails.org/caching_with_rails.html

http://railslab.newrelic.com/scaling-rails