对获取列表的 api 接口进行集合缓存,假设获取前 10 条文章列表。
# model
class Article
include Mongoid::Document
include Mongoid::Timestamps
field :title, type: String
field :content, type: String
end
# controller
class ArticlesController < Api::BaseController
def index
@articles = Article.order_by(id: :asc).limit(10)
end
end
# view
json.cache! [@articles] do
json.articles @articles do |article|
json.call(article, :title, :content)
end
end
# 第一次调用api
MONGODB | localhost:27017 | _development.find | STARTED | {"find"=>"articles", "filter"=>{}, "limit"=>10, "sort"=>{"id"=>1}}
# 第二次调用api
MONGODB | localhost:27017 | _development.find | STARTED | {"find"=>"articles", "filter"=>{}, "limit"=>10, "sort"=>{"id"=>1}}
# 处理类数据的缓存键(新增)
module ClassDataCacheKeyAble
extend ActiveSupport::Concern
included do
after_create do
self.class.refresh_class_cache_version
end
after_update do
self.class.refresh_class_cache_version
end
after_destroy do
self.class.refresh_class_cache_version
end
end
class_methods do
def cache_key_with_version
"#{cache_key}-#{cache_version}"
end
def cache_version
Redis::Counter.new("class_cache_version:#{cache_key}").value
end
def refresh_class_cache_version
Redis::Counter.new("class_cache_version:#{cache_key}").increment
end
def cache_key
name.tableize
end
end
end
# model调整
class Article
include Mongoid::Document
include Mongoid::Timestamps
include ClassDataCacheKeyAble # 引入模块
field :title, type: String
field :content, type: String
end
# view调整
json.cache! [Article] do
json.articles @articles do |article|
json.call(article, :title, :content)
end
end
# 第一次调用api
MONGODB | localhost:27017 | _development.find | STARTED | {"find"=>"articles", "filter"=>{}, "limit"=>10, "sort"=>{"id"=>1}}
# 第二次调用api,没有查询数据库
相对优化前,减少了一次数据的列表查询,但多了一次获取全局更新键的 redis 查询,总体下来性能还是很好的,本地简单测试了一下近两倍左右,随着数据库数量的增加,优化空间会更大。
适用场景:模型总体数据变化不大,例子仅说明问题使用。
大家有没什么更好的方案,欢迎留言指正。