Rails.cache相關知識


可能里面的一些知識已經不被大家使用了,但是作為學習,我想和大家分享一下個人關於Rails.cache的淺顯的認識,望大家指教。

1.Rails.cache是什么

它是Rails中的緩存,擁有所有緩存的共同點,它是為了提升網站性能。

2.Rails中Rails.cache的存儲系統。

本身常用的有四種,可以根據不同的環境進行選擇不同的存儲系統。

  • FileStore,利用文件系統緩存文件,能夠在多個應用間共享緩存,但是這樣會不斷的增加硬盤使用。
  • MemoryStore, Ruby 進程使用共同的內存,默認大小為32M,,雖然可以更改這個限制,但是不適合大型的部署,並且它不能用於多個應用共享緩存。
  • MemCacheStore, 這種方式使用 Memcached 最為后端緩存服務,它提供了高性能的、集中式的緩存服務,可以在多個應用間共享緩存,這是一種適合中大型商業應用的選擇。
  • NullStore, 適合開發和測試環境的配置,它不會儲存任何東西,但是可以正常調試 Rails.cache 中的方法。

3. Rails項目的自定義配置存儲系統。

這里我以使用redis來作為Rails.cache的存儲系統進行介紹

3.1 為什么會選redis

因為是key-value的結構,同時使用redis,能夠通過 redis 的命令快速實現,比關系型數據庫擁有更快的讀寫速度,且更適合儲存非結構化數據。

3.2 如何配置

  • 確保你的系統已經安裝了redis數據庫(具體怎么安裝,這里不做闡述)
  • 在你的gemfile文件中,加入gem 'redis-rails'這一行,然后bundle install。
  • 一般初始化的默認配置可以在development.rb,production.rb,test.rb文件中單獨設置適用於不同環境的存儲系統;我選擇直接在application.rb中寫配置信息。
    配置信息(必須):
    config.action_controller.perform_caching = true # 確保開啟緩存,dev環境下默認是沒有開啟的。
    config.cache_store = :redis_store, {
        host: 'localhost',
        port: '6379',
        db: 1, # 這是整數,可以理解為redis數據庫中的表標志,默認是16個數據庫,可從0-15中取值
        password: '',
        expires_in: 5.hours # 過期時間的設置
    }

4. Rails.cache常見用法。

4.1 首先如何設置開啟緩存

  1. production上默認開啟了緩存

  2. development上默認不開啟

    配置方法一(常用):

    # 在development.rb文件中添加
    config.action_controller.perform_caching = true
    # 設置緩存的頁面存放的地址(不能修改,默認是public)
    config.action_controller.page_cache_directory = "#{Rails.root.to_s}/public"
    

    配置方法二(Rails5版本之后開始支持):

    # 執行任務,會在tmp文件下創建caching-dev.txt和restart.txt文件
    rake dev:cache
    

    經過個人測試,兩者不能混用,混用存在的問題:
    1.如果你使用rake dev:cache,就不能在development.rb中去修改緩存默認存儲的地址,一旦修改,緩存就會失效。
    2.一旦你是用rake dev:cache來開啟緩存,那么就要使用rake dev:cache來關閉緩存(不能通過config.action_controller.perform_caching = false來操作,無法起作用),如果要自己測試,那你一定要首先把之前緩存的文件給刪除掉,不然不管你怎么操作,只要public下有該文件,就一直讀該文件。

    如果看一下rake dev:cache的源碼,我們能找到另外一種方式來關閉

    # 源碼 rake任務
    namespace :dev do
        desc "Toggle development mode caching on/off"
        task :cache do
            Rails::DevCaching.enable_by_file
        end
    end
    # 源碼:通過文件來判斷是否開啟緩存
    FILE = "tmp/caching-dev.txt"
    def enable_by_file
        FileUtils.mkdir_p("tmp")
    
        if File.exist?(FILE)
          delete_cache_file
          puts "Development mode is no longer being cached."
        else
          create_cache_file
          puts "Development mode is now being cached."
        end
    
        FileUtils.touch "tmp/restart.txt"
    end
    

    所以,很明顯,我們可以通過刪除tmp下的restart.txt和cache-dev.txt來關閉緩存。
    個人建議:還是在development.rb文件中自己配置比較靈活

4.2 如何使用3種緩存方式(片段緩存,頁面緩存,方法緩存),從Rails4開始,頁面緩存和方法緩存已經轉換為gem的形式,只有片段緩存是Rails默認的。

  • 頁面緩存

    一句話總結:使用緩存的頁面來代替action請求對應的頁面,這個和緩存系統無關。
    默認緩存的文件直接放在public目錄下。

    頁面緩存現在已經被單獨作為一個gem,需要在你的Gemfile中加入 gem "actionpack-page_caching"

    真正的代碼實現:

      # 一個控制器
      class HuanCunController < ApplicationController
          # 使用緩存
          caches_page :welcome_show
          
          # 緩存的頁面對應的控制器
          def welcome_show
              
          end
      end
    

    welcome_show頁面

    Hello,welcom!! current_time_now:<%= Time.now.strftime('%Y-%m-%d %H:%M:%S.%L') %>

    沒有使用緩存的時候,每次請求的頁面都是實時變化的,可以看current_time_now的值。
    使用緩存后,會在你配置保存目錄的文件下生成對應的靜態html文件。

  • 方法緩存

    在Gemfile文件中加入gem 'actionpack-action_caching'
    為了便於觀察,選擇redis作為緩存系統。

    使用方法緩存的代碼如下:
        class Car::CarsController < ApplicationController
          caches_action :index
          def index
        
          end
        end      
    

    監控方法:

    打開終端,輸入redis-cli,然后輸入monitor,可以監控redis的存儲情況。
    調用該index方法,會產生一個key:"get""views/locahost:3003/car/cars"

    以后每次再去調用該index,你會發現redis的monitor中都是顯示如下信息:說明緩存成功,不再每次去方法中執行,而是直接從redis中去取。

    1560408837.780396 [2 [::1]:54380] "get" "views/localhost:3003/car/cars"
    1560408838.140465 [2 [::1]:54380] "get" "views/localhost:3003/car/cars"
    1560408838.667096 [2 [::1]:54380] "get" "views/localhost:3003/car/cars"
    

    過期時間的問題:

    如果你沒有設置過期時間,那么他的過期時間使用redis設置的過期時間。

    如果想查看過期時間,進入redis控制台,然后選擇你使用的數據庫id,例如(查出來的時間是以秒為單位)

        myMacBook-Pro redis-cli
        127.0.0.1:6379>select 2
        OK
        127.0.0.1:6379[2]> TTL "views/localhost:3003/car/cars"
        (integer) 13620
        127.0.0.1:6379[2]>=
    

    如果想自己設置過期時間,可以直接查看gem 'actionpack-action_caching'這個gem的文檔

  • 片段緩存
    片段緩存是rails中最常用的一種緩存方式,主要是在頁面中進行局部緩存。

     在index.html.erb頁面中
     <% cache 'test_index' do %>
     <%= Time.now.strftime('%Y-%m-%d %H:%M:%S.%L') %>
    <% end %>
    

    這個其實和方法緩存的監控的方式一樣,你會發現會生成"views/car/cars/index:61696bc621e5ee68531c6a58dfaf4da3/test_index"這樣的key,同時也能查到過期時間。
    每次你去刷新頁面,都會在redis中去請求這個key值對應的value值。
    如果想自己設置過期時間為2小時,可以這樣設置

    <% cache 'test_index',expires_in: 2.hours do %>
     <%= Time.now.strftime('%Y-%m-%d %H:%M:%S.%L') %>
    <% end %>
    

如果你想讓這個"views/car/cars/index:61696bc621e5ee68531c6a58dfaf4da3/test_index"的key失效,你可以使用expire_fragment('views/car/cars/index:61696bc621e5ee68531c6a58dfaf4da3/test_index') ,但是在實際應用中我們無法查到這個key的具體值,所以我們可以這樣設置:

<% cache 'test_index', {skip_digest: true} do %>
 <%= Time.now.strftime('%Y-%m-%d %H:%M:%S.%L') %>
<% end %>

這樣’test_index’將會被作為cache key被緩存起來,如果想要使他失效,只要在對應的action里調用就expire_fragment('test_index')就行,如果不加 {skip_digest: true},那么是無法直接調用expire_fragment('test_index')的。
可以簡單的查看一下生成這個片段name的源碼:

def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil)
        if skip_digest
          name
        else
          fragment_name_with_digest(name, virtual_path)
        end
end
可以很明顯的看出,如果skip_digest是true,將直接返回頁面中寫的name。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM