假设您有一个显示最新帖子的页面片段,您将在30分钟后将其过期.我在这里使用Rails.
<% cache("recent_posts", :expires_in => 30.minutes) do %> ... <% end %>
显然,如果片段存在,您不需要进行数据库查找以获取最新的帖子,因此您也应该能够避免这种开销.
我现在正在做的是在控制器中这样的东西似乎工作:
unless Rails.cache.exist? "views/recent_posts" @posts = Post.find(:all, :limit=>20, :order=>"updated_at DESC") end
这是最好的方法吗?安全吗?
我不明白的一件事是,为什么密钥是" recent_posts
"用于片段和" views/recent_posts
",以便稍后检查,但我看了之后memcached -vv
看到它正在使用它.另外,我不喜欢手动输入" recent_posts
" 的重复,最好将它保存在一个地方.
想法?
Evan Weaver的Interlock Plugin解决了这个问题.
如果您需要不同的行为,例如更精细的控制,您也可以轻松地自己实现这样的功能.基本思想是将控制器代码包装在一个仅在视图需要该数据时才实际执行的块中:
# in FooController#show @foo_finder = lambda{ Foo.find_slow_stuff } # in foo/show.html.erb cache 'foo_slow_stuff' do @foo_finder.call.each do ... end end
如果您熟悉ruby元编程的基础知识,那么很容易将其包含在您喜欢的更干净的API中.
这比将finder代码直接放在视图中要好:
将发现者代码按照惯例保留在开发人员期望的位置
使视图不知道模型名称/方法,允许更多的视图重用
我认为cache_fu可能在其中一个版本/分叉中具有类似的功能,但不能具体回忆.
从memcached获得的优势与缓存命中率直接相关.注意不要浪费您的缓存容量,并通过多次缓存相同的内容而导致不必要的错过.例如,不要同时缓存一组记录对象及其html片段.通常,片段缓存将提供最佳性能,但它实际上取决于应用程序的细节.