重学rails: rails8 cache
rails 缓存相关
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
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,这个才可以真正加速,看这个视频
<%= 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 方法有read
、write
、delete
、exist?
和fetch
。
如何测试
Benchmark
来测试是否真实有提升性能。
def index
benchmark = Benchmark.measure do
@posts = Post.all
render
end
logger.info "Benchmark: #{benchmark.real * 1000}ms"
end
API缓存
- https://stackoverflow.com/questions/66941133/how-to-cache-rails-api-actions
- https://docs.pingcode.com/ask/ask-ask/99317.html
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