Dav*_*ave 11 caching ruby-on-rails in-memory ruby-on-rails-5
我正在使用Rails 5.我当前正在使用Rails内存缓存来缓存数据库查询结果,例如,这是在我的state.rb模型中...
def self.cached_find_by_iso_and_country_id(iso, country_id)
if iso
Rails.cache.fetch("#{iso.strip.upcase} #{country_id}") do
find_by_iso_and_country_id(iso.strip.upcase, country_id)
end
end
end
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何创建第二个内存中的Rails缓存(我需要一个用于存储我从Internet下载的文件),这不会干扰我上面的查询缓存?我不希望文件缓存中的条目导致我的查询缓存中的条目被逐出.
是的,你可以用Rails做到这一点.您需要创建第二个缓存并将其作为全局变量在应用程序中使用,然后根据上下文调用相应的缓存.每个缓存都分配了自己的内存块(默认为32 MB),如果一个缓存填满,则不会影响其他缓存.这是完成的ActiveSupport::Cache::MemoryStore.new.
我将证明这两个缓存不会相互影响:
首先,生成两个用于测试缓存的文本文件,一个10 MB,一个30 MB:
dd if=/dev/zero of=10M bs=1m count=10
dd if=/dev/zero of=30M bs=1m count=30
Run Code Online (Sandbox Code Playgroud)
打开Rails控制台并将其读入字符串:
ten = File.read("10M"); 0
thirty = File.read("30M"); 0
Run Code Online (Sandbox Code Playgroud)
存储ten在缓存中:
Rails.cache.fetch("ten") { ten }; 0
Run Code Online (Sandbox Code Playgroud)
确认数据已缓存:
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
Run Code Online (Sandbox Code Playgroud)
存储thirty在缓存中:
Rails.cache.fetch("thirty") { thirty }; 0
Run Code Online (Sandbox Code Playgroud)
确认未保存(太大而无法在作为字符串扩展时保存在缓存中):
Rails.cache.fetch("thirty")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
确认这已经破坏了整个缓存:
Rails.cache.fetch("ten")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
现在创建第二个缓存并确认其行为与原始缓存相同:
store = ActiveSupport::Cache::MemoryStore.new
store.fetch("ten") { ten }; 0
store.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
store.fetch("thirty") { thirty }; 0
store.fetch("thirty")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
store.fetch("ten")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
现在有两个空缓存:store和Rails.cache.让我们确认它们是独立的:
Rails.cache.fetch("ten") { ten }; 0
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
store.fetch("thirty") { thirty }; 0 # bust the `store' cache
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
Run Code Online (Sandbox Code Playgroud)
如果两个缓存受到干扰,那么最后一次store.fetch调用会破坏两个缓存.它只是破产store.
要在应用程序中实现第二个缓存,请创建初始化程序config/initializers/cache.rb并添加:
$cache = ActiveSupport::Cache::MemoryStore.new
Run Code Online (Sandbox Code Playgroud)
在代码中调用新缓存的方式与以下方式相同Rails.cache:
$cache.fetch("foo") { "bar" }
Run Code Online (Sandbox Code Playgroud)
其中一些细节来自这个答案.新缓存支持其他选项; 有关自定义缓存的更多信息,请查看MemoryStore和Cails with Rails.
此解决方案适用于小型应用程序.请注意MemoryStore文档中的这条评论:
如果您正在运行多个Ruby on Rails服务器进程(如果您使用mongrel_cluster或Phusion Passenger就是这种情况),那么这意味着Rails服务器进程实例将无法彼此共享缓存数据,这可能在这种情况下不是最合适的缓存.
| 归档时间: |
|
| 查看次数: |
1578 次 |
| 最近记录: |