Redis 缓存存储
部署注意事项:请务必使用专用 Redis 缓存,而不是指向持久化 Redis 服务器(例如,用作 Active Job 队列的服务器)。Redis 无法很好地应对混合使用模式,并且默认情况下不会过期缓存条目。
Redis 缓存服务器设置指南:redis.io/topics/lru-cache
-
支持原生 Redis、hiredis 和
Redis::Distributed
。 -
支持使用
Redis::Distributed
在多个 Redis 之间进行 Memcached 风格的切片。 -
容错。如果 Redis 服务器不可用,不会抛出异常。
Cache
的所有获取操作都将是未命中,写入操作将被丢弃。 -
本地缓存。块/中间件范围内的热内存主缓存。
-
read_multi
和write_multi
支持 Redis mget/mset。使用Redis::Distributed
4.0.1+ 进行分布式 mget 支持。 -
delete_matched
支持 Redis KEYS glob 模式。
- C
- D
- I
- N
- R
- S
常量
DEFAULT_ERROR_HANDLER | = | -> (method:, returning:, exception:) do if logger logger.error { "RedisCacheStore: #{method} 失败,返回 #{returning.inspect}: #{exception.class}: #{exception.message}" } end ActiveSupport.error_reporter&.report( exception, severity: :warning, source: "redis_cache_store.active_support", ) end |
DEFAULT_REDIS_OPTIONS | = | { connect_timeout: 1, read_timeout: 1, write_timeout: 1, } |
MAX_KEY_BYTESIZE | = | 1024 |
如果键超过 1kB,则使用 Active Support 摘要进行截断 |
属性
[R] | max_key_bytesize | |
[R] | redis |
类公共方法
new(error_handler: DEFAULT_ERROR_HANDLER, **redis_options) 链接
创建一个新的 Redis 缓存存储。
有四种方式提供缓存使用的 Redis 客户端::redis
参数可以是 Redis 实例或返回 Redis 实例的代码块,或者 :url
参数可以是字符串或字符串数组,用于创建 Redis 实例或 Redis::Distributed
实例。
Option Class Result
:redis Proc -> options[:redis].call
:redis Object -> options[:redis]
:url String -> Redis.new(url: …)
:url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …])
默认情况下不会设置命名空间。如果 Redis 缓存服务器与其他应用程序共享,请提供命名空间:namespace: 'myapp-cache'
。
默认情况下启用压缩,阈值为 1kB,因此大于 1kB 的缓存值会自动压缩。通过传递 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
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 149 def initialize(error_handler: DEFAULT_ERROR_HANDLER, **redis_options) universal_options = redis_options.extract!(*UNIVERSAL_OPTIONS) if 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 @max_key_bytesize = MAX_KEY_BYTESIZE @error_handler = error_handler super(universal_options) end
supports_cache_versioning?() 链接
宣布支持缓存版本控制。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 63 def self.supports_cache_versioning? true end
实例公共方法
cleanup(options = nil) 链接
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 282 def cleanup(options = nil) super end
clear(options = nil) 链接
清除所有 Redis 服务器上的整个缓存。如果缓存已命名空间,则可以在共享服务器上安全使用。
故障安全:引发错误。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 290 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
decrement(name, amount = 1, options = nil) 链接
使用 Redis decrby 原子操作递减缓存的整数值。返回更新后的值。
如果键未设置或已过期,它将被设置为 -amount
cache.decrement("foo") # => -1
要设置特定值,请调用 write
并传递 raw: true
cache.write("baz", 5, raw: true)
cache.decrement("baz") # => 4
递减非数值或未使用 raw: true
写入的值将失败并返回 nil
。
故障安全:引发错误。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 267 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
delete_matched(matcher, options = nil) 链接
支持 Redis KEYS glob 模式
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。
故障安全:引发错误。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 201 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.del(*keys) unless keys.empty? end until cursor == "0" end end end end
increment(name, amount = 1, options = nil) 链接
使用 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
。
故障安全:引发错误。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 240 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
inspect() 链接
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 164 def inspect "#<#{self.class} options=#{options.inspect} redis=#{redis.inspect}>" end
read_multi(*names) 链接
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 172 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
stats() 链接
从 Redis 服务器获取信息。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 301 def stats redis.then { |c| c.info } end