【问题标题】:Caching Serializers, fails to cache associations缓存序列化程序,无法缓存关联
【发布时间】:2014-06-11 09:47:31
【问题描述】:

我正在尝试使用 Active Model Serializer 实现一些缓存;这是我的序列化器。

class ServiceFieldSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :meta_description, :content, :practitioner_term, :avatar, :slug
  has_many :services
  embed :id, include: true

  cached
  delegate :cache_key, to: :object

  def services
    object.services.published
  end

  def avatar
    object.image_url :avatar if object.image.present?
  end
end

服务序列化器

class ServiceSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :meta_description, :content, :practitioner_term, :avatar, :slug
  has_one :service_field
  embed :id

  cached
  delegate :cache_key, to: :object

  def avatar
    object.image_url :avatar if object.image.present?
  end
end

输出“y ServiceSerializer.new(Service.first)”

object: !ruby/ActiveRecord:Service
  attributes:
    id: 4
    name: ADHD Coaching
    description: Bliv klogere på hvorfor du har det damp i hovede
    service_field_id: 2
    created_at: 2014-02-18 08:08:41.755177000 Z
    updated_at: 2014-04-29 08:30:44.111671000 Z
    content: tihihi
    image:
    published: true
    meta_description:
    slug: adhd-coaching
    practitioner_term:

我的问题是,当我有缓存调用时,我的 json 响应看起来像这样。

service_fields: []->
0: {id:2, name:Coaching, description:Det bliver du glad for, meta_description:, content:,…}
1: {id:1, name:Massage, description:Massage er godt for krop og alt i hele verden., meta_description:null,…}
2: {id:3, name:Terapi, description:Noget med nogle møder, meta_description:null,…}

如您所见,缺少关联的服务,如果我从序列化程序中删除缓存,则服务就在那里。

我做错了什么?

Rails 版本:4.0.5

AMS 版本:0.8.1

【问题讨论】:

  • 您是否尝试清除缓存并确保您不会以某种方式获取旧的缓存值?
  • 我多次重新启动 memcached,是的,我一直盯着日志,是的 :)。
  • 不要唠叨,但有没有机会在测试时甚至不使用 memcached?也许您正在以某种方式使用默认文件存储?
  • 缓存设置为delli 'config.cache_store = :dalli_store',带有perform_caching。正如我所写,我可以在日志中看到缓存也在被写入,并且在重新启动 memcached 时它会重置。 :-)
  • @MartinElvar 序列化程序 ServiceSerializer 存在吗?

标签: ruby-on-rails ruby-on-rails-4 active-model-serializers


【解决方案1】:

你没有做错任何事......事实上,我花了一个多星期的时间来弄清楚为什么这不起作用,我发现 AMS 缓存不适用于侧载关系......

但如果您想继续找出问题所在...然后查看this AMS fork,我们使用 AMS 缓存问题中的信息解决了这个特定问题...

需要注意的一点......通过使用这个 gem,我们能够减少查询集合所花费的时间......但它几乎对加载 1 个对象没有影响......只有集合......我们是能够将一些收集时间从 75% 减少到 10% 我知道仅减少 10% 并不是那么好......这就是为什么我们现在(3 天前)转移到 JBuilder......老实说你我没弄清楚它的缓存是如何工作的

编辑

关于 jbuilder 和缓存时间...使用带有适当部分缓存(片段缓存)的 jbuilder,当集合未缓存时,我们能够获得大约 40 毫秒的响应时间,而当它被缓存时,响应时间大约为 15 毫秒...响应缓存前的时间大约为 130 毫秒(因为片段缓存不会使整个对象及其关系失效......只有更改的部分)......所以我建议使用带有演示者层的 jbuilder(如Draper gem)和jbuilder multi cache更好的集合缓存

【讨论】:

  • 我很害怕,目前 AMS 回购似乎相当安静。出于好奇,与 AMS 相比,您使用 JBuilder 获得了多少性能提升?因为随着我的应用程序变得越来越复杂,我面临着一些令人讨厌的加载时间,即使是急切加载。
  • 在接受您的回答之前,我会再给这个问题一些时间,可能会有人碰巧知道解决方法:)。
  • true...这就是为什么我们在 asknative 中的每个新项目中都迁移到 JBuilder :D ...我也没有添加这个答案来获得赏金或任何东西...我添加了这是为了得到关于我的结论的反馈,即 AMS 真的很慢,特别是与侧载关系...我无法判断 JBuilder 的性能...事实上我正在努力掌握它并有一个工作的东西启动并运行......我的经验不到一周,但看起来很有希望
  • 我可以看到你也在使用 Emberjs,所以同样的故事:)。对于我将近 1.5 秒的加载,我最终为重型模型创建了一个预览序列化程序;我在我的索引操作中使用它,这给我带来了大约 60% 的性能提升,如果你需要显示所有内容,这将无济于事。目前我们没有时间将 json 序列化程序切换到 jbuilder,但如果 AMS 完全失控,我会调查它。 :)
  • 试试 fork...你应该正在解决问题的路上...如果你发现任何东西,你可以将 PR 添加到 fork 因为我们非常需要这要使用 AMS 正确完成
【解决方案2】:

所以我在谷歌的时候,我发现这篇帖子http://homeonrails.com/2014/03/fast-rails-api/ 似乎解决了这个问题,通过手动缓存它。

@services_fields = ServiceField.includes(:services)
json = Rails.cache.fetch 'test' do
  ActiveModel::Serializer.build_json(self, @services_fields, {}).to_json
end

respond_with json

这会呈现正确的 JSON。

随时发布替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2011-09-13
    • 2021-12-14
    • 1970-01-01
    • 2014-09-13
    相关资源
    最近更新 更多