Как использовать несколько кешей в рельсах? (серьезно)
Я хотел бы использовать 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
в инициализаторы среды.