美文网首页
我所知道的rails cache机制

我所知道的rails cache机制

作者: 摸鱼少年 | 来源:发表于2015-07-29 22:53 被阅读0次

    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机制

          本文链接:https://www.haomeiwen.com/subject/mfnmqttx.html