我在我的应用程序中看到了一些性能问题,我想知道我的缓存是否正常工作,或者我是否误解了错误的配置。我使用的是 快捷的jsonapi 用于序列化,它自带一个内置的缓存选项。
比方说
class BooksController < ApplicationController
...
def index
@books = Books.includes(:author, :publisher).with_attached_cover.all
BookSerializer.new(@book, { include: [:author, :publisher]}).serializable_hash.to_json
end
...
end
和
class BookSerializer
include FastJsonapi::ObjectSerializer
cache_options store: Rails.cache, namespace: 'fast-jsonapi', expires_in: 24.hours
belongs_to :author
belongs_to :publisher
attributes :all_the_book_attributes_im_too_lazy_to_list
end
也让我们假设我有大约5000本书,2000个作者和100个出版商,所以我希望缓存能在性能上有很大的不同。
然而,事实上,我看到我的数据库在启用或不启用缓存的情况下都会出现同样的问题,而且响应时间非常慢。此外,当检查我的缓存时,它似乎只缓存了每一本单独的书,而不是作为一个整体的序列化哈希。
现在我想知道我是否完全错过了序列化器中缓存的目的,或者我是否需要在我的控制器中添加一些额外的层?如果是的话,有什么办法可以用DRY的方式来实现吗?会不会和序列器的缓存冲突?那序列化器中的缓存到底有什么作用呢?
我知道有多种方式的cache可以使用。我只是不知道该组合哪些,是否要防止这些层之间的冲突。
就像我可以看到你想缓存这个JSON响应。
为这个查询添加一个缓存键。你需要这个来使响应无效,当书籍随着时间的推移而改变。
# model book.rb
class Book < ApplicationRecord
...
def self.cache_key
{
serializer: 'books',
stat_record: Book.maximum(:updated_at)
}
end
...
end
在你的控制器中,使用该键从缓存中获取数据,或者做一个新的查询。
class BooksController < ApplicationController
...
def index
@books = Rails.cache.fetch(Book.cache_key) do
BookSerializer.new(
Books.includes(:author, :publisher).with_attached_cover.all,
{
include: [:author, :publisher]
}
).serializable_hash.to_json
end
render json: @books
end
...
end
你也可以看看页面缓存。
另外,如果你有5000个条目,你应该考虑分页。