Rails ActiveSupport::Cache 缓存存储详解

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

ruby 复制代码
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。

ruby 复制代码
# config/environments/*.rb 或 config/application.rb

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

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

代码例子

ruby 复制代码
# 写入缓存
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,只需指定缓存目录。

ruby 复制代码
# 基本配置
config.cache_store = :file_store, "/path/to/cache/directory"

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

代码例子

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

ruby 复制代码
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 客户端)。

ruby 复制代码
# 单服务器
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 }

代码例子

ruby 复制代码
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'

ruby 复制代码
# 基本配置
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
}

代码例子

ruby 复制代码
# 普通使用
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 服务
  • 配置相对复杂(尤其集群)
  • 内存占用稍高(功能多)

综合对比表格

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

总结建议

  • 新项目 :强烈推荐 RedisCacheStore(Rails 官方首选)。
  • 本地开发/测试 :使用 MemoryStore(默认)。
  • 极简单机生产 :选择 FileStore
  • 已有 Memcached 基础设施 :继续使用 MemCacheStore
相关推荐
茶杯梦轩2 小时前
从零起步学习并发编程 || 第二章:多线程与死锁在项目中的应用示例
java·服务器·后端
大尚来也2 小时前
深入理解 Android 消息机制:Handler、Looper 与 MessageQueue 的协同工作原理
后端
sp422 小时前
Spring Task 任务调度可视化管理
后端·spring
q***76562 小时前
工作中常用springboot启动后执行的方法
java·spring boot·后端
黄俊懿3 小时前
【架构师从入门到进阶】第一章:架构设计基础——第二节:架构设计原则
分布式·后端·中间件·架构
代码N年归来仍是新手村成员4 小时前
OpenClaw本地部署 + AWS Bedrock Claude 4.5 模型
后端·云计算·aws
树獭叔叔4 小时前
深度解析 GRPO:DeepSeek R1 背后“悟道”的逻辑引擎
后端·aigc·openai
是店小二呀4 小时前
MySQL 深度实践:表的约束及其在数据完整性中的作用
后端