1

我在我的应用程序中看到了一些性能问题,想知道我的缓存是否正常工作,或者我是否误解/错误配置了任何东西。我正在使用带有内置缓存选项的fast-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

还假设我有 2000 位作者和 100 家出版商的大约 5000 本书,所以我希望缓存会对性能产生很大影响。

然而,事实上我看到我的数据库在启用或不启用缓存的情况下以相同的方式命中,并且响应时间非常慢。此外,在检查我的缓存时,它似乎只缓存了每一本书,而不是整个序列化的哈希。

现在我想知道我是否完全错过了在序列化程序中缓存的目的,或者我是否需要在控制器中添加一些额外的层?如果是,是否有解决方案以 DRY 方式执行此操作?会不会和序列化器的缓存冲突?那么,序列化程序中缓存的目的是什么?

我知道我可以使用多种方式/缓存层。我只是不确定要合并哪些以及是否要防止这些层之间的任何冲突。

4

1 回答 1

0

就像我可以看到你想要缓存这个 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 个条目,你应该考虑分页。

于 2020-05-23T20:51:32.360 回答