重学rails: rails8 cache

rails 缓存相关
更新于: 2024-11-05 07:17:31

dev 开启/关闭缓存

实际上是 tmp/caching-dev.txt 的文件存在与否

默认情况下,在开发模式下, 缓存是启用的:memory_store。这不适用于 Action Controller 缓存,因为默认情况下禁用缓存。

$ bin/rails dev:cache
Development mode is now being cached.
$ bin/rails dev:cache
Development mode is no longer being cached.

禁用缓存

要禁用缓存,请设置cache_store:null_store

rails page cache

这个已经被 rails4 放弃了,因为存在诸多缺点,详情使用手册

Rails 移除页面缓存的主要原因是为了提高灵活性和安全性。页面缓存虽然能提供很高的性能,但也带来了一些问题:

安全性:页面缓存可能会缓存敏感数据,尤其是在需要身份验证的场景下,这会导致信息泄露。

灵活性:页面缓存不支持动态内容更新。对于现代应用程序,用户的交互和内容常常是动态的,页面缓存在这些情况下会限制开发的灵活性。

维护复杂性:使用页面缓存可能导致在更新页面内容时需要手动清除缓存,增加了维护的复杂性。

更好的替代方案:Rails 提供了其他更灵活的缓存机制,比如 fragment caching 和 low-level caching,允许开发者更细粒度地控制缓存的行为。

因此,虽然页面缓存在某些情况下很高效,但考虑到现代 Web 应用的需求,Rails 决定移除这一机制。

几个重要的点

  • config.action_controller.perform_caching = true 打开缓存
  • By default, files are stored below the public directory of your Rails application
gem 'actionpack-page_caching'

rails action cache

也被 rails 放弃了,但其实是 db 与 controller 之间的缓存,详细使用手册

gem 'actionpack-action_caching'

片段缓存(fragment cache)

第一次访问的时候,会产生一条缓存:views/products/index:bea67108094918eeba42cd4a6e786901/products/1

<% @products.each do |product| %>
  <% cache product do %>
    <%= render product %>
  <% end %>
<% end %>

在 Ruby on Rails 中,片段缓存是一种优化技术,用于缓存视图中的小部分内容,以提高应用程序的性能。在你提供的代码示例中,片段缓存用于缓存每个产品的渲染结果。下面是对这段代码的逐步解释:

遍历产品@products.each do |product| 是一个循环,遍历实例变量 @products 中的每个 product 对象。

缓存块cache product do 开始一个缓存块。Rails 会根据 product 对象的唯一标识符(通常是 ID)来生成缓存的键。这样,如果 product 的内容没有改变,下一次请求时会直接使用缓存的结果,而不必重新渲染。

渲染产品<%= render product %> 用于渲染每个产品的视图。这个部分的输出将被缓存。

结束块<% end %> 结束了缓存块和循环。

通过使用片段缓存,可以显著减少数据库查询和视图渲染的时间,尤其是当产品列表比较大或者单个产品渲染比较复杂时。总的来说,片段缓存帮助提高了响应速度和应用的可扩展性。

按特定条件缓存

<% cache_if admin?, product do %>
  <%= render product %>
<% end %>

collection cache,这个才可以真正加速,看这个视频

https://www.youtube.com/watch?v=t4bugdvKEag

<%= render partial: 'products/product', collection: @products, cached: true %>

low-level-caching

直接使用 Rails.cache.fetch 来实现

Rails 的低级缓存(low-level caching)主要是指 Rails 提供的一些直接操作缓存的方法,这些方法通常比高层次的缓存机制(如 fragment caching 或 action caching)更灵活但也更复杂。

直接控制:低级缓存允许你直接操作缓存存储(例如内存、文件或其他后端存储)。你可以自由地设置、读取和删除缓存内容。

使用 Rails.cache:Rails 提供了一个全局的 Rails.cache 对象,你可以通过它进行低级缓存操作。例如:

  • 写入缓存Rails.cache.write(key, value, options)
  • 读取缓存Rails.cache.read(key)
  • 删除缓存Rails.cache.delete(key)

缓存块:你可以使用缓存块来在缓存未命中时计算值并自动存入缓存。例如:

result = Rails.cache.fetch('some_key') do
  # 计算并返回结果
end

过期时间:你可以为缓存设置过期时间,以控制缓存数据的生命周期:

Rails.cache.write('some_key', value, expires_in: 10.minutes)

缓存版本:你还可以为缓存添加版本号,以便在数据更新时使旧缓存失效。

缓存存储后端:Rails 支持多种缓存后端,包括内存存储、文件存储、Memcached、Redis 等。你可以在 config/environments 文件中配置缓存存储。

使用场景

  • 当你需要缓存复杂的计算结果,避免重复计算时。
  • 当你需要在应用的不同部分共享数据时。
  • 在高并发情况下,减少数据库查询的次数。

低级缓存适合需要细粒度控制的场景,但同时也要求开发者更好地管理缓存的有效性和一致

缓存配置

缓存存储的大小是有限制的,可以通过将选项发送:size给初始化程序来指定(默认为 32Mb)。当缓存超过分配的大小时,将进行清理,并删除最近最少使用的条目。

# 使用内存
config.cache_store = :memory_store, { size: 64.megabytes }
# 使用文件缓存
# 在不同主机上运行的服务器进程可以使用共享文件系统共享缓存,但不建议使用这种设置。由于缓存会不断增长直至磁盘满,因此建议定期清除旧条目。
# 如果没有提供明确说明,则这是默认的缓存存储实现(在"#{root}/tmp/cache/")
config.cache_store = :file_store, "/path/to/cache/directory"

几个API

主要 API 方法有readwritedeleteexist?fetch

如何测试

Benchmark 来测试是否真实有提升性能。

def index
  benchmark = Benchmark.measure do
    @posts = Post.all
    render
  end
  logger.info "Benchmark: #{benchmark.real * 1000}ms"
end

API缓存

The gem adds these methods to your controllers by including ActionController::Caching in ActionController::Base (see here). To add this behaviour to controllers that don't extend from ActionController::Base, simply include ActionController::Caching.

class ApplicationController < ActionController::API
  include ActionController::Caching
end