【问题标题】:Jbuilder Rails caching is slowerJbuilder Rails 缓存速度较慢
【发布时间】:2015-05-25 07:00:07
【问题描述】:

我尝试将缓存与集合一起使用(具有多种解决方案),但问题是当我尝试缓存时,响应会变慢 考虑以下集合的示例,该集合为其中的每个项目(大约 25 个项目)呈现 2 个部分

json.data do
  json.array! @organizations do |organization|
    json.partial! 'api/v1/organizations/organization', organization: organization
    json.partial! 'api/v1/organizations/links', organization: organization
  end
end

没有缓存的平均响应时间约为 38 毫秒(平均)

现在有了缓存

json.data do
  json.array! @organizations do |organization|
    json.cache! organization do
      json.partial! 'api/v1/organizations/organization', organization: organization
      json.partial! 'api/v1/organizations/links', organization: organization
    end
  end
end

使用 jbuilder 默认缓存和 dalli 存储已正确安装和配置(我可以验证没有缓存未命中)

平均响应约为 59 毫秒(平均)

使用Cache Digest上的语法

json.data do
  json.cache! @organizations do
    json.partial! 'api/v1/organizations/organization', collection: @organizations, as: :organization
    json.partial! 'api/v1/organizations/links', collection: @organizations, as: :organization
  end
end

平均响应时间约为 41 毫秒(平均),响应与其他响应不同

# Instead of getting
[{ data:{}, links:{} }, {{ data:{}, links:{} }]
# I get
[{ data:{}, data:{}, links:{}, links:{} }]

但是文件的缓存摘要是一个非常大的字符串,很容易超过 unix 最大文件名长度。 例如,这是文件名。

Cache write: jbuilder/organizations/5509f9284162643526000000-20150322012449497000000/organizations/5509e5924162643056020000-20150320223230684000000/organizations/550b54d8416264add2040000-20150321004501311000000/organizations/550e35704162640a98030000-20150322032224768000000/organizations/550e357b4162640a98050000-20150322032235260000000/organizations/550e35834162640a98080000-20150322032243162000000/organizations/550e35894162640a980a0000-20150322032249767000000/organizations/550e35904162640a980c0000-20150322032256464000000/organizations/550e35944162640a980e0000-20150322032300519000000/organizations/550e35984162640a98100000-20150322032304428000000/organizations/550e359c4162640a98120000-20150322032308542000000/organizations/550e35a04162640a98140000-20150322032312514000000/organizations/550e35a54162640a98160000-20150322032317066000000/organizations/550e35a84162640a98180000-20150322032320850000000/organizations/550e35ac4162640a981a0000-20150322032324716000000/organizations/550e35b04162640a981c0000-20150322032328643000000/organizations/550e35b54162640a981e0000-20150322032333651000000/organizations/550e35ba4162640a98200000-20150322032338114000000/organizations/550e35bd4162640a98220000-20150322032341889000000/organizations/550e35c14162640a98240000-20150322032345602000000/organizations/550e35c54162640a98260000-20150322032349739000000/3fcda1f9c320ab4284da56b4b2337cf5`

我也累了Jbuilder Cache Multi

json.data do
  json.cache_collection! @organizations do |organization|
    json.partial! 'api/v1/organizations/organization', organization: organization
    json.partial! 'api/v1/organizations/links', organization: organization
  end
end

响应时间约为 57 毫秒(平均)

加上 jbuilder 缓存和 multi 我在日志中得到了很多这些

  Cache digest for app/views/api/v1/organizations/index.json.jbuilder: 3a51096b9c8da6a2cdb5b5a33ee58ea4
  Cache digest for app/views/api/v1/organizations/_organization.json.jbuilder: 4a1f1d49c90fdd867d88701f8a3fd6e1
  Cache digest for app/views/api/v1/organizations/_links.json.jbuilder: f2a881e125f95421d566edd571fdec73
  Cache digest for app/views/api/v1/organizations/index.json.jbuilder: 3a51096b9c8da6a2cdb5b5a33ee58ea4
  Cache digest for app/views/api/v1/organizations/_organization.json.jbuilder: 4a1f1d49c90fdd867d88701f8a3fd6e1
  Cache digest for app/views/api/v1/organizations/_links.json.jbuilder: f2a881e125f95421d566edd571fdec73
  Cache digest for app/views/api/v1/organizations/index.json.jbuilder: 3a51096b9c8da6a2cdb5b5a33ee58ea4
  Cache digest for app/views/api/v1/organizations/_organization.json.jbuilder: 4a1f1d49c90fdd867d88701f8a3fd6e1

我的实现或机器或本地环境有问题吗? Rails 4.2.0 和 Jbuilder 2.2.11

I also posted this issue to jbuilder #259

【问题讨论】:

    标签: caching ruby-on-rails-4 memcached jbuilder ruby-on-rails-4.2


    【解决方案1】:

    为了详细说明我的引述,截至目前(JBuilder 的 v2.2.12),只有在以下一项或两项为真时,在 JBuilder 中缓存部分内容才真正值得:

    • 您可以跳过平均而言比访问缓存更昂贵的 AR 查询(或计算)

      去缓存通常是在通常的 Rails 堆栈中的网络调用,虽然数据库查询可能很昂贵,但通过网络获取序列化的 ActiveSupport blob,然后反序列化的成本在 Ruby 中写入哈希是昂贵的,并且必须在 Ruby VM 中完成。这对性能不利。

    • 生成的 JSON blob 的大小很小

      因此,如果您有一个小查询,但生成了大量 JSON,那么您将很快遇到性能下降的问题,因为该 blob 从 ActiveSupport blob 反序列化,然后再次输出为原始 JSON。请记住,缓存不存储原始 JSON,而是一种序列化的中间格式。这意味着,对于存储在缓存中的每一个额外的 JSON 字节,您将通过线路(来自序列化的 AS 表示)多出大约 4 个字节,并且可能花费与仅计算无论如何都是部分的。

    如果您有一个生成巨大 JSON blob 的端点,我的建议是在控制器中手动有条件地渲染 blob,并将其作为原始字符串缓存在 Rails.cache 中。不时地重新计算所有 JSON 的成本可能低于每次调用时通过 JBuilder 的缓存机制。

    【讨论】:

      【解决方案2】:

      作为这个答案的时间......这就是 jbuilder 的工作方式......正如我可以从 github issue 中引用的那样

      @vincentwoo

      问题在于 jbuilder 缓存相当幼稚 - 它基本上将一个巨大的 activerecord blob 的序列化版本转储到缓存存储中,然后将其拉出、反序列化,然后最终将其序列化为 JSON。

      未来,jbuilder 有望直接作用于字符串,但在那之前,我认为 jbuilder 缓存最好不要使用俄罗斯娃娃风格。

      和@rwz(合作者之一)

      目前,缓存仅在允许跳过一些 AR 查询或您使用计算量非常大的视图帮助程序时才提供好处。

      当您已经获取记录并且只执行基本提取时,缓存只会减慢速度。

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-23
        • 1970-01-01
        • 2014-09-28
        • 2010-12-08
        • 2019-03-02
        相关资源
        最近更新 更多