我所知道的rails cache机制

cache就是缓存,善用缓存可以极大提高网站的性能。rails作为一个full-stack的web应用开发框架,它在这方面做了很多的努力。
我们依次从底层到客户端来了解一下缓存机制的相关细节。

  1. rails框架自动进行SQL缓存
    rails在内存中缓存了每次sql查询的结果,那么在同一次经过ActionPack时,相同的sql会命中缓存,而提高性能。

  2. ActiveRecord层缓存
    在rails的model层中可以手动缓存某些业务结果到对应的缓存存储系统里。

Rails.cache.fetch(key, expires_in: 1.hour) do 
....
end

其中cache的key可以自己指定。这里又不得不提到dog pile effect,也即缓存过期时,多个请求竞争访问,从而导致服务器卡顿现象。race_condition_ttl 和expires_in组合使用可以防止这个问题。

  1. ActionController层
    action缓存:rails4中移除了action的缓存,需要gem(actionpack-action_caching)才能实现。缓存了action response的html结果,但可以进入action-pack进行authenticaion等判断。其内部实现主要是借助fragment cache和各种callback实现的。
before_action :authentication, only: :show
cache_action :show, expires_in: 1.hour

page缓存:rails4中移除了page的缓存,需要gem(actionpack-page_caching)才能实现。缓存了action response的html,无需进入action-pack,直接可以返回结果,速度是最快的。

cache_page :show, expires_in: 1.hour
  1. ActionView层缓存
    随着互联网应用的逐渐发展,页面复杂程度加剧,后端无法做到整页面的缓存,只能分割成片段。片段缓存的概念逐渐强化。
    fragement 缓存:片段缓存是对应action的,所以如果要跨action调用片段缓存时,需要指定action。
    如在controller A,action one的response html中要调用controller B, action two的片段缓存
<% cache(action: 'two', controller: 'B', action_suffix: 'namespace') do %>
  Thing.all
 <% end%>

其中,action_suffic是在一个response html中存在多个cache时用以区分的namespace。
cache的key又两种指定方式:1. cache(Model_instance) 生成的key格式为Model/instance_id-updated_at;2.使用helper method自己生成。
片段缓存也嵌套使用,形成俄罗斯套娃(Russian Doll Caching)的特殊形式。
片段缓存的过期方式:expire_fragment(controller: 'A', action: 'one', action_suffix: 'namespace')

  1. browser端的缓存支持
    http协议中包含了ETag、If-None-Match 和 If-Modified-Since之类的header,主要是为了方便实现browser的get请求的缓存使用。
class SomeController < ApplicationController
    def show
      @thing = Thing.find(params[:id])
      if stale?(@thing)
        respond_to do |format|
          .......
        end
      end 
    end
end

其中stale?(@thing)stale?(last_modified: @thing.updated_at.utc, etag: @thing.cache_key)等价。
如果没有respond_to的复杂逻辑,也可以直接使用fresh_when @thing

以上是我所知道的rails中cache的基本内容。

你可能感兴趣的:(我所知道的rails cache机制)