【发布时间】:2014-06-08 22:38:36
【问题描述】:
好的,在我回答实际问题之前,这篇文章有点罗嗦,所以精简版基本上与使用 RABL 模板的缓存预热有关。当调用 Rabl.render vs API 调用时,生成的缓存没有相同的缓存键。当直接使用 Rabl.render 时,当通过 API 调用相同的模板时,我应该期望缓存键匹配吗?
K,现在结束了..
我在 Heroku 上有一个 Rails API 服务器。我使用俄罗斯娃娃缓存对 RABL 进行了很多优化,以提高集合中底层对象的重用性。虽然,我仍然留下了集合缓存,当用户在第一次请求时生成的缓存是体验的负担(例如 1+ 次 api 调用)。
在调试示例 API 调用时,我在给定对象上获得以下缓存操作。
...api/v1/activities/26600:
Cache read: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7
Cache generate: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7
Cache write: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7
所以对于同一个对象,在调用 ...api/v1/activities 时(在上述调用之后)我得到了所需的缓存命中:
Cache read: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7
Cache fetch_hit: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7
这很好用。下一步是避免让第一个/任何 API 调用花费时间生成缓存。
所以我一直在寻求缓存预热技术,以便在用户访问它们之前生成这些集合。一个建议是使用wget 作为直接访问API 的一种方式(参见https://stackoverflow.com/a/543988/451488)。但这增加了 Heroku web dynos 的负担,所以我想通过 sidekiq 工作人员在后台缓存预热。
RABL 提供了一种直接从代码(https://github.com/nesquena/rabl#rendering-templates-directly)呈现模板的方法,这对于这个用例来说绝对是正确的方法。因此,我的意图是在 API 调用之前通过一些事件调用 RABL 引擎(例如 - 用户登录事件)。
因此,对于上面的 API 示例,我会在 rails 控制台中调用以下命令并期望缓存命中。
irb(main):002:0> @activity = Activity.find(26600)
irb(main):003:0> Rabl.render(@activity, 'api/v2/activities/show_no_root', :view_path => 'app/views', :format => :json)
Cache read: rabl/activities/26600-20140423170223588554000//hash
Cache generate: rabl/activities/26600-20140423170223588554000//hash
Cache write: rabl/activities/26600-20140423170223588554000//hash
出乎意料,我没有得到缓存命中,但很明显缓存键不一样,因为缺少尾随哈希签名。我不确定为什么在这种情况下缓存键会有所不同。我无法为 RABL 模板预热缓存。
更新
结果是尾随缓存键中的哈希是模板哈希。
Cache digest for api/v1/activities/_show.rabl: d30440d18014c72014a05319af0626f7
虽然这告诉了我该哈希的来源,但仍然不清楚为什么直接调用 Rabl::Renderer 也不会使用它。
【问题讨论】:
标签: ruby-on-rails json caching heroku rabl