Как использовать несколько кэшей в рельсах? (серьезно) - PullRequest
14 голосов
/ 26 октября 2011

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

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

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

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

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

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

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

Ответы [ 2 ]

18 голосов
/ 21 марта 2012

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"}
7 голосов
/ 14 декабря 2014

В инициализаторе вы можете просто поставить:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...