Как использовать несколько кешей в рельсах? (серьезно)

Я хотел бы использовать 2 кэша - по умолчанию по умолчанию и memcache, хотя абстрактно это не имеет значения (я думаю), которые два.

В памяти по умолчанию используется один, где я хочу загружать небольшие и редко изменяющиеся данные. Я использую память на сегодняшний день. Я держу кучу материалов типа данных домена из базы данных там, у меня также есть небольшие данные из внешних источников, которые я обновляю каждые 15 мин - 1 час.

Недавно я добавил memcache, потому что теперь я обслуживаю несколько более крупных активов. Сорт, как я это понял, но это больше ~ килобайт, относительно небольшое количество (сотни) и сильно кэшируемое - они меняются, но обновление раз в час, вероятно, слишком много. Этот набор может расти, но он разделяет все хосты. Освежители дороги.

Первый набор данных уже некоторое время использует кеш памяти по умолчанию и хорошо себя ведет. Memcache идеально подходит для второго набора данных.

Я настроил memcache, и он отлично работает для второго набора данных. Проблема в том, что из-за моего существующего кода, который был сделан "мышлением", он был в локальной памяти, я делаю несколько поездок в memcache для каждого запроса, что увеличивает мою задержку.

Итак, я хочу использовать 2 кэша. Мысли?

(примечание: memcache работает на разных машинах (машинах), чем мой сервер. Даже если бы я запускал его локально, у меня есть парк хостов, поэтому он не будет локальным для всех. Кроме того, я хочу избежать необходимости просто получайте больше машин. Хотя я, вероятно, мог бы решить эту проблему, сделав память больше и просто используя память (данные действительно не такие большие), это не решает проблему, поскольку я масштабируюсь, поэтому она будет просто пинать банку.)

Ответ 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 в инициализаторы среды.