是的,你可以用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
打开Rails控制台并将其读入字符串中:
ten = File.read("10M")
thirty = File.read("30M")
将10
存储在缓存中:
Rails.cache.fetch("ten") { ten }; 0
确认数据已被缓存:
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
将 30
存储在缓存中:
Rails.cache.fetch("thirty") { thirty }; 0
确认这个没有被保存(由于展开后作为字符串太大无法保存在缓存中):
Rails.cache.fetch("thirty")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
确认这已经破坏了整个缓存:
Rails.cache.fetch("ten")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
现在创建第二个缓存,并确认它的行为与原始缓存完全相同:
store = ActiveSupport::Cache::MemoryStore.new
store.fetch("ten") { ten }
store.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
store.fetch("thirty") { thirty }
store.fetch("thirty")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
store.fetch("ten")[0..10]
NoMethodError: undefined method `[]' for nil:NilClass
现在有两个空缓存:
store
和
Rails.cache
。让我们确认它们是独立的:
Rails.cache.fetch("ten") { ten }
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
store.fetch("thirty") { thirty }
Rails.cache.fetch("ten")[0..10]
=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
如果两个缓存相互干扰,那么最后一个
store.fetch
调用将会破坏两个缓存。但它只会破坏
store
。
要在您的应用程序中实现第二个缓存,请创建一个初始化器
config/initializers/cache.rb
并添加以下内容:
$cache = ActiveSupport::Cache::MemoryStore.new
在你的代码中调用新缓存与调用 Rails.cache
的方式相同:
$cache.fetch("foo") { "bar" }
这些细节来自于这个答案。新的缓存支持额外的选项,可以查看MemoryStore和使用Rails进行缓存以获取有关自定义缓存的更多信息。
此解决方案适用于小型应用程序。请注意MemoryStore文档中的评论:
如果您运行多个Ruby on Rails服务器进程(如果使用mongrel_cluster或Phusion Passenger,则是这种情况),则这意味着Rails服务器进程实例将无法共享缓存数据,并且在这种情况下可能不是最合适的缓存。