Rails ActiveSupport::Cache 缓存存储详解

18 阅读3分钟

Rails 的 ActiveSupport::Cache 提供了多种缓存存储实现,所有存储都使用统一的 API:

Rails.cache.read(key)
Rails.cache.write(key, value, expires_in: 1.hour)
Rails.cache.fetch(key) { expensive_operation }  # 经典缓存模式
Rails.cache.delete(key)
Rails.cache.clear  # 清空整个缓存

以下分别详细讲解 MemoryStoreFileStoreMemCacheStoreRedisCacheStore

1. ActiveSupport::Cache::MemoryStore

配置方式

MemoryStore 是开发环境的默认缓存,无需额外 gem。

# config/environments/*.rb 或 config/application.rb

# 基本配置(默认无限容量)
config.cache_store = :memory_store

# 带选项:限制缓存大小(单位字节)和线程安全
config.cache_store = :memory_store, { size: 64.megabytes, threadsafe: true }

代码例子

# 写入缓存
Rails.cache.write("current_user_name", "alex", expires_in: 10.minutes)

# 读取缓存
name = Rails.cache.read("current_user_name")

# fetch:不存在时执行块并缓存结果
user_count = Rails.cache.fetch("user_count", expires_in: 5.minutes) do
  User.count
end

优缺点

优点

  • 速度最快(纯内存,无 IO/网络开销)
  • 配置最简单,无外部依赖
  • 适合快速开发和测试

缺点

  • 数据不持久化,进程重启即丢失
  • 每个 Ruby 进程独立,无法跨进程/服务器共享
  • 受进程内存限制,大数据量易导致 OOM

2. ActiveSupport::Cache::FileStore

配置方式

无需额外 gem,只需指定缓存目录。

# 基本配置
config.cache_store = :file_store, "/path/to/cache/directory"

# 推荐配置
config.cache_store = :file_store, Rails.root.join("tmp", "cache")

代码例子

(API 与其他存储完全相同)

Rails.cache.write("featured_posts", posts, expires_in: 1.hour)
posts = Rails.cache.fetch("featured_posts") { Post.featured.limit(10).to_a }

优缺点

优点

  • 数据持久化到磁盘,重启不丢失
  • 无外部服务依赖
  • 多进程可共享(共享同一文件系统)

缺点

  • 磁盘 IO 性能较差,高并发时瓶颈明显
  • 缓存文件过多时文件系统压力大(inode 耗尽风险)
  • 不适合分布式多服务器部署(NFS 性能差)

3. ActiveSupport::Cache::MemCacheStore

配置方式

需要 gem:gem 'dalli'(推荐的 Memcached 客户端)。

# 单服务器
config.cache_store = :mem_cache_store, "localhost:11211"

# 多服务器 + 选项
config.cache_store = :mem_cache_store,
  ["cache-01.example.com:11211", "cache-02.example.com:11211"],
  { namespace: "myapp", compress: true, expires_in: 1.day }

代码例子

Rails.cache.write("stats_dashboard", stats_data, expires_in: 30.minutes)
data = Rails.cache.fetch("stats_dashboard") { calculate_complex_stats }

优缺点

优点

  • 原生分布式,支持多服务器集群
  • 高并发性能优秀
  • 成熟的 LRU 淘汰机制

缺点

  • 需要单独部署和维护 Memcached 服务
  • 数据不持久化,重启丢失
  • 功能相对单一(仅 key-value)
  • 新项目已逐渐被 Redis 取代

4. ActiveSupport::Cache::RedisCacheStore

配置方式

需要 gem:gem 'redis'

# 基本配置
config.cache_store = :redis_cache_store, { url: "redis://localhost:6379/0" }

# 生产推荐配置
config.cache_store = :redis_cache_store, {
  url: ENV["REDIS_URL"] || "redis://redis:6379/0",
  namespace: "myapp:cache",
  expires_in: 90.minutes,
  compress: true
}

代码例子

# 普通使用
Rails.cache.write("leaderboard", ranking, expires_in: 1.hour)

# Redis 独有高级特性:标签失效
Rails.cache.write("post:123", post, raw: true, tags: ["posts", "user:#{post.user_id}"])
Rails.cache.delete_tagged("posts")  # 批量失效

优缺点

优点

  • 分布式 + 可持久化(RDB/AOF)
  • 性能接近 Memcached,功能丰富(标签失效、原子操作)
  • 与 Rails 生态深度集成(Action Cable、Sidekiq 等可共用)
  • 官方推荐,社区支持最好

缺点

  • 需要部署和维护 Redis 服务
  • 配置相对复杂(尤其集群)
  • 内存占用稍高(功能多)

综合对比表格

对比维度MemoryStoreFileStoreMemCacheStoreRedisCacheStore
配置复杂度最低中等中等
外部依赖Memcached + dalli gemRedis + redis gem
持久性可配置
分布式支持有限(需共享文件系统)优秀优秀(集群/哨兵)
性能极高(纯内存)中等(磁盘 IO)高(接近 Memcached)
容量/淘汰机制可限制条目数磁盘空间限制LRU多种策略(LRU/LFU/TTL 等)
高级功能基本基本基本(CAS)丰富(标签失效、原子操作、Pub/Sub)
最佳场景开发/测试、单进程单服务器中小型生产传统高并发分布式现代中大型分布式(官方推荐)
主要优点最快、无依赖持久化、无外部服务分布式成熟、高并发功能最全、生态最佳、可持久化
主要缺点不共享、不持久IO 瓶颈、不适合分布式不持久、功能单一需要维护 Redis、配置稍复杂

总结建议

  • 新项目:强烈推荐 RedisCacheStore(Rails 官方首选)。
  • 本地开发/测试:使用 MemoryStore(默认)。
  • 极简单机生产:选择 FileStore
  • 已有 Memcached 基础设施:继续使用 MemCacheStore