假设您的页面片段显示最近的帖子,并在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代码直接放在视图中:
>保留开发人员期望的finder代码
>保持视图对模型名称/方法无知,允许更多的视图重用
我认为cache_fu可能在其中一个版本/分支中具有相似的功能,但不能特别回想起来.
从memcached获得的优势与您的缓存命中率直接相关.小心不要浪费你的缓存容量,并通过多次缓存相同的内容造成不必要的错过.例如,不要同时缓存一组记录对象以及它们的html片段.通常片段缓存将提供最佳性能,但这取决于您的应用程序的具体情况.