将memcached和Rails的片段和对象缓存结合起来的最佳方法 [英] Best way to combine fragment and object caching for memcached and Rails

查看:299
本文介绍了将memcached和Rails的片段和对象缓存结合起来的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设你有一段显示最新帖子的页面,并在30分钟内过期。

 <%cache(recent_posts,:expires_in => 30.minutes)do %GT; 
...
<%end%>>

显然,如果片段存在,您不需要执行数据库查找来获取最近的帖子,所以你应该能够避免这种开销。



我现在正在做的是类似于控制器中的这样的工作:

 除非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的互锁插件解决了这个问题。

如果你需要不同的行为,比如更细粒度的控制,你也可以很容易地实现这样的事情。基本的想法是将你的控制器代码包装在一个只有在视图需要这些数据时才被实际执行的块中:

 #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中。



这比直接放置取景器代码更好在视图中:


  • 使开发人员期望的查找程序代码保持原样

  • 保持视图无视模型名称/方法,允许更多的视图重用



我认为cache_fu可能在其版本/分支之一中具有类似的功能,但无法具体回忆。



您从memcached获得的优势直接关系到d到你的缓存命中率。注意不要浪费缓存容量,并多次缓存相同的内容导致不必要的错失。例如,不要同时缓存一组记录对象以及它们的html片段。通常片段缓存将提供最好的性能,但它实际上取决于您的应用程序的具体情况。


Lets say you have a fragment of the page which displays the most recent posts, and you expire it in 30 minutes. I'm using Rails here.

<% cache("recent_posts", :expires_in => 30.minutes) do %>
  ...
<% end %>

Obviously you don't need to do the database lookup to get the most recent posts if the fragment exists, so you should be able to avoid that overhead too.

What I'm doing now is something like this in the controller which seems to work:

unless Rails.cache.exist? "views/recent_posts"
  @posts = Post.find(:all, :limit=>20, :order=>"updated_at DESC")
end

Is this the best way? Is it safe?

One thing I don't understand is why the key is "recent_posts" for the fragment and "views/recent_posts" when checking later, but I came up with this after watching memcached -vv to see what it was using. Also, I don't like the duplication of manually entering "recent_posts", it would be better to keep that in one place.

Ideas?

解决方案

Evan Weaver's Interlock Plugin solves this problem.

You can also implement something like this yourself easily if you need different behavior, such as more fine grained control. The basic idea is to wrap your controller code in a block that is only actually executed if the view needs that data:

# 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

If you're familiar with the basics of ruby meta programming it's easy enough to wrap this up in a cleaner API of your taste.

This is superior to putting the finder code directly in the view:

  • keeps the finder code where developers expect it by convention
  • keeps the view ignorant of the model name/method, allowing more view reuse

I think cache_fu might have similar functionality in one of it's versions/forks, but can't recall specifically.

The advantage you get from memcached is directly related to your cache hit rate. Take care not to waste your cache capacity and cause unnecessary misses by caching the same content multiple times. For example, don't cache a set of record objects as well as their html fragment at the same time. Generally fragment caching will offer the best performance, but it really depends on the specifics of your application.

这篇关于将memcached和Rails的片段和对象缓存结合起来的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆