class ActiveSupport::Cache::RedisCacheStore
Хранилище кэша Redis
Примечание по развертыванию: используйте выделенный Redis для кэша, а не постоянный сервер Redis (например, используемый в качестве очереди Active Job). Redis плохо справляется со смешанными сценариями использования и по умолчанию не удаляет записи кэша по истечении срока действия.
Руководство по настройке сервера кэша Redis: redis.io/topics/lru-cache
-
Поддерживает vanilla Redis, hiredis и
Redis::Distributed. -
Поддерживает шардирование по аналогии с Memcached между серверами Redis с помощью
Redis::Distributed. -
Устойчиво к сбоям. Если сервер Redis недоступен, исключения не возникают. Все запросы
Cacheзавершаются промахом, а операции записи отбрасываются. -
Локальный кэш. Быстрый кэш в памяти, действующий в пределах блока или промежуточного ПО.
-
Поддержка
read_multiиwrite_multiдля Redis mget/mset. Для поддержки распределенного mget используйтеRedis::Distributedверсии 4.0.1 или новее. -
Поддержка
delete_matchedдля шаблонов Redis KEYS.
Константы
- DEFAULT_ERROR_HANDLER
- DEFAULT_REDIS_OPTIONS
Атрибуты
Общедоступные методы класса
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 155
def initialize(error_handler: DEFAULT_ERROR_HANDLER, **redis_options)
universal_options = redis_options.extract!(*UNIVERSAL_OPTIONS)
redis = redis_options[:redis]
already_pool = redis.instance_of?(::ConnectionPool) ||
(redis.respond_to?(:wrapped_pool) && redis.wrapped_pool.instance_of?(::ConnectionPool))
if !already_pool && pool_options = self.class.send(:retrieve_pool_options, redis_options)
@redis = ::ConnectionPool.new(**pool_options) { self.class.build_redis(**redis_options) }
else
@redis = self.class.build_redis(**redis_options)
end
@error_handler = error_handler
super(universal_options)
end Создает новое хранилище кэша Redis.
Есть несколько способов передать клиент Redis, используемый кэшем:
-
Параметр
:redisможет быть:-
Экземпляром Redis.
-
Экземпляром
ConnectionPool, оборачивающим экземпляр Redis. -
Блоком, возвращающим экземпляр Redis.
-
-
Параметр
:urlможет быть:-
Строкой, используемой для создания экземпляра Redis.
-
Массивом строк, используемым для создания экземпляра
Redis::Distributed.
-
Если итоговый экземпляр Redis еще не является ConnectionPool, он будет обернут в него с помощью ActiveSupport::Cache::Store::DEFAULT_POOL_OPTIONS. Эти параметры можно переопределить с помощью параметра :pool, а пул можно отключить, указав +:pool: false+.
Option Class Result
:redis Object -> options[:redis]
:redis Proc -> options[:redis].call
:url String -> Redis.new(url: …)
:url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …]) По умолчанию пространство имен не задается. Укажите его, если сервер кэша Redis используется совместно с другими приложениями: namespace: 'myapp-cache'.
По умолчанию сжатие включено, а порог составляет 1 kB: кэшируемые значения размером более 1 kB автоматически сжимаются. Отключите сжатие, передав compress: false, или измените порог, передав compress_threshold: 4.kilobytes.
По умолчанию для записей кэша не устанавливается срок действия. Предполагается, что Redis настроен на использование политики вытеснения, которая автоматически удаляет ключи, используемые реже всего или давно, при достижении максимального объема памяти. Инструкции по настройке сервера кэша см. на странице redis.io/topics/lru-cache.
По умолчанию TTL для предотвращения состояний гонки не задан. Его можно использовать, чтобы избежать одновременной массовой записи в кэш при истечении срока действия часто используемых записей. Подробнее см. в разделе ActiveSupport::Cache::Store#fetch.
Если задано skip_nil: true, результаты nil не будут кэшироваться:
cache.fetch('foo') { nil }
cache.fetch('bar', skip_nil: true) { nil }
cache.exist?('foo') # => true
cache.exist?('bar') # => false
ActiveSupport::Cache::Store::new # File activesupport/lib/active_support/cache/redis_cache_store.rb, line 60 def self.supports_cache_versioning? true end
Объявляет поддержку версионирования кэша.
Общедоступные методы экземпляра
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 301 def cleanup(options = nil) super end
Удаляет записи с истекшим сроком действия. Redis обрабатывает это автоматически, удаляя наименее недавно или наименее часто используемые записи, поэтому ручная очистка не поддерживается.
ActiveSupport::Cache::Store#cleanup # File activesupport/lib/active_support/cache/redis_cache_store.rb, line 309
def clear(options = nil)
failsafe :clear do
if namespace = merged_options(options)[:namespace]
delete_matched "*", namespace: namespace
else
redis.then { |c| c.flushdb }
end
end
end Очищает весь кэш на всех серверах Redis. Безопасно для совместно используемых серверов, если кэш использует пространство имен.
Защита от сбоев: вызывает ошибки.
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 286
def decrement(name, amount = 1, options = nil)
options = merged_options(options)
key = normalize_key(name, options)
instrument :decrement, key, amount: amount do
failsafe :decrement do
change_counter(key, -amount, options)
end
end
end Уменьшает кэшированное целочисленное значение с помощью атомарного оператора Redis decrby. Возвращает обновленное значение.
Если ключ не задан или срок его действия истек, ему будет присвоено значение -amount:
cache.decrement("foo") # => -1
Чтобы задать конкретное значение, вызовите write, передав raw: true:
cache.write("baz", 5, raw: true)
cache.decrement("baz") # => 4
Уменьшение нечислового значения или значения, записанного без raw: true, завершится ошибкой и вернет nil.
Чтобы прочитать значение позднее, вызовите read_counter:
cache.decrement("baz") # => 3
cache.read_counter("baz") # 3
Защита от сбоев: вызывает ошибки.
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 210
def delete_matched(matcher, options = nil)
unless String === matcher
raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}"
end
pattern = namespace_key(matcher, options)
instrument :delete_matched, pattern do
redis.then do |c|
cursor = "0"
# Fetch keys in batches using SCAN to avoid blocking the Redis server.
nodes = c.respond_to?(:nodes) ? c.nodes : [c]
nodes.each do |node|
begin
cursor, keys = node.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE)
node.unlink(*keys) unless keys.empty?
end until cursor == "0"
end
end
end
end Поддерживает шаблоны Redis KEYS с подстановочными знаками:
h?llo matches hello, hallo and hxllo h*llo matches hllo and heeeello h[ae]llo matches hello and hallo, but not hillo h[^e]llo matches hallo, hbllo, ... but not hello h[a-b]llo matches hallo and hbllo
Используйте \ для экранирования специальных символов, если требуется сопоставить их буквально.
Подробнее см. на странице redis.io/commands/KEYS.
Защита от сбоев: вызывает ошибки.
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 254
def increment(name, amount = 1, options = nil)
options = merged_options(options)
key = normalize_key(name, options)
instrument :increment, key, amount: amount do
failsafe :increment do
change_counter(key, amount, options)
end
end
end Увеличивает кэшированное целочисленное значение с помощью атомарного оператора Redis incrby. Возвращает обновленное значение.
Если ключ не задан или срок его действия истек, ему будет присвоено значение amount:
cache.increment("foo") # => 1
cache.increment("bar", 100) # => 100
Чтобы задать конкретное значение, вызовите write, передав raw: true:
cache.write("baz", 5, raw: true)
cache.increment("baz") # => 6
Увеличение нечислового значения или значения, записанного без raw: true, завершится ошибкой и вернет nil.
Чтобы прочитать значение позднее, вызовите read_counter:
cache.increment("baz") # => 7
cache.read_counter("baz") # 7
Защита от сбоев: вызывает ошибки.
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 173
def inspect
"#<#{self.class} options=#{options.inspect} redis=#{redis.inspect}>"
end # File activesupport/lib/active_support/cache/redis_cache_store.rb, line 181
def read_multi(*names)
return {} if names.empty?
options = names.extract_options!
options = merged_options(options)
keys = names.map { |name| normalize_key(name, options) }
instrument_multi(:read_multi, keys, options) do |payload|
read_multi_entries(names, **options).tap do |results|
payload[:hits] = results.keys.map { |name| normalize_key(name, options) }
end
end
end Считывает сразу несколько значений. Возвращает хэш запрошенных ключей -> полученных значений.
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 320
def stats
redis.then { |c| c.info }
end Получает информацию с серверов Redis.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.