【问题标题】:How to use multiple caches in rails? (for real)如何在rails中使用多个缓存? (真的)
【发布时间】:2011-10-26 05:27:08
【问题描述】:

我想使用 2 个缓存——内存中默认的一个和一个 memcache 一个,尽管抽象地说(我认为)哪两个并不重要。

内存中的默认值是我要加载小的且很少更改的数据的地方。到目前为止,我一直在使用内存。我从数据库中保留了一堆“域数据”类型的东西,我还有一些来自外部来源的小数据,我每 15 分钟到 1 小时刷新一次。

我最近添加了内存缓存,因为我现在提供一些更大的资产。我如何进入这个有点复杂,但这些更大〜千字节,数量相对较少(数百),并且高度可缓存 - 它们会改变,但每小时刷新一次可能太多了。这个集合可能会增长,但它在所有主机之间共享。刷新很昂贵。

第一组数据使用默认内存缓存已经有一段时间了,一直表现良好。 Memcache 非常适合第二组数据。

我已经调整了 memcache,它对第二组数据非常有效。问题是,由于我的现有代码“认为”它位于本地内存中,因此每个请求我都会多次访问 memcache,这增加了我的延迟。

所以,我想使用 2 个缓存。想法?

(注意:memcache 与我的服务器在不同的机器上运行。即使我在本地运行它,我也有一组主机,所以它不会是所有本地的。另外,我想避免需要只是得到更大的机器.即使我可能可以通过扩大内存并只使用内存来解决这个问题(数据真的没那么大),但这并不能解决我扩展的问题,所以它只会踢罐子。)

【问题讨论】:

    标签: ruby-on-rails-3 caching


    【解决方案1】:

    ActiveSupport::Cache::MemoryStore 是您想要使用的。 Rails.cache 使用 MemoryStore、FileStore 或在我的情况下使用 DalliStore :-)

    您可以拥有 ActiveSupport::Cache::MemoryStore 的全局实例并使用它或创建一个具有单例模式的类来保存该对象(更清洁)。将 Rails.cache 设置为另一个缓存存储,并将此单例用于 MemoryStore

    下面是这个类:

    module Caching
      class MemoryCache
          include Singleton
    
          # create a private instance of MemoryStore
          def initialize
            @memory_store = ActiveSupport::Cache::MemoryStore.new
          end
    
          # this will allow our MemoryCache to be called just like Rails.cache
          # every method passed to it will be passed to our MemoryStore
          def method_missing(m, *args, &block)
            @memory_store.send(m, *args, &block)
          end
      end
    end
    

    这是如何使用它:

    Caching::MemoryCache.instance.write("foo", "bar")
    => true
    Caching::MemoryCache.instance.read("foo")
    => "bar"
    Caching::MemoryCache.instance.clear
    => 0
    Caching::MemoryCache.instance.read("foo")
    => nil
    Caching::MemoryCache.instance.write("foo1", "bar1")
    => true
    Caching::MemoryCache.instance.write("foo2", "bar2")
    => true
    Caching::MemoryCache.instance.read_multi("foo1", "foo2")
    => {"foo1"=>"bar1", "foo2"=>"bar2"}
    

    【讨论】:

      【解决方案2】:

      在初始化器中你可以放:

      MyMemoryCache = ActiveSupport::Cache::MemoryStore.new

      那么你可以这样使用它:

      MyMemoryCache.fetch('my-key', 'my-value')
      

      等等。

      请注意,如果只是为了性能优化(并且取决于时间到期),那么在您的测试环境中禁用它可能不是一个坏主意,如下所示:

      if Rails.env.test?
        MyMemoryCache = ActiveSupport::Cache::NullStore.new
      else
        MyMemoryCache = ActiveSupport::Cache::MemoryStore.new
      end
      

      Rails 已经通过允许您在环境初始化程序中设置不同的值 config.cache_store 来提供此功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-24
        • 2014-02-28
        • 2017-03-27
        • 1970-01-01
        • 2014-02-20
        • 2020-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多