2010-10-25 38 views
2

我正在努力将片段高速缓存添加到既有登录名又有匿名用户的Rails 3站点,并且需要根据内容何时过期来控制部分页面过期在整个网站显示更新。在此过程中,我发现memcached不支持expire_fragment的正则表达式,所以现在我正在寻找解决方法。解决memcached在Rails片段高速缓存中缺少通配符失效的问题

对于匿名用户来说,这不是一个大问题。我创建了像'frontpage-new-shows'或'schedule-weekly-forecast-10/24/10'这样的缓存键,并在Show模型中创建一个新条目或者在下周通过清扫器进行修改。这工作得很好。

我的问题是登录的用户。他们每个人都有自己的自定义时间表,所以我的密钥看起来像'schedule-user-jschuur-10/10/24',其中jschuur是帐户的用户名。我了解到,使用基于日期的约定时,它们会自然过期,但我也希望在当天(或一周)的日程安排中显示相关更改的那一天,显式过期缓存时间表的所有片段。

事实证明,memcached无法做到我需要的那种通配符到期(schedule-user - 。* - 10/10/24)。这意味着我需要某种解决方案来存储在memcached中的中央查找键中发布的所有密钥,或者基于我为我发送给memcached的密钥,Rails/Ruby以某种方式在内部执行此操作。

我假设前者是更好的解决方案。我的问题是,我如何以最有效的方式来做到这一点,所以我不会将所有时间都保存下来,而不是再次击中数据库。我可以将数组或散列存储在memcached中,检索整个事物,循环如果匹配,删除它们并将散列存储回去。听起来这对于几百甚至上千用户来说可能很好,但这真的是最好的选择吗?

有人已经解决了这个问题并发布了解决方案吗?

有一点要考虑的是,几乎所有的缓存目前正与在视图中陈述完成后,向ActiveRelations面向尚未准备发射查询,像这样的:

<% if current_user %> 
    <% if current_user.saved_shows_count %> 
    <% cache "schedule-user-#{current_user.username}-#{(Time.now + 3.hours).to_date.end_of_week.strftime('%D')}" do %> 
     <% if @shows.any? %> 
     <%= render :partial => "schedule/schedule", :locals => { :shows => @shows } %> 
     <% end %> 
    <% end %> 
... 

该网站是在Heroku上托管,我使用dalli gem作为客户端。

回答

5

编辑:有一些问题,这是与达利宝石写,做一个读引发“元帅数据太短”或“无效编组数据在内存缓存”对我来说。不知道它是否也适合你。

虽然有点诡异,但可以使用命名空间,然后增加命名空间,从而使使用它创建的所有密钥无效。为此,请首先在初始化程序(或任何地方)中使用Rails.cache.write("frontpage-new-shows-namespace", "1", {:raw => true})设置名称空间。设置每个缓存时,请将Rails.cache.read("frontpage-new-shows-namespace")添加到您希望的任何位置的散列密钥中(这在哪里并不重要)。使名称空间中创建的所有缓存键失效就像Rails.cache.increment("frontpage-new-shows-namespace", 1)一样简单。您可以将Rails.cache.read("frontpage-new-shows-namespace")作为全局变量添加,从而消除用于创建缓存键的memcache搜索,然后在执行缓存名称空间增量时更新此变量。

祝你好运,我希望这有助于。

+0

花了我几分钟的时间仔细研究了一下,但现在我明白了。我可以在之前的过滤器中设置当前的名称空间ID,这些页面具有缓存的内容,这样我只需要时就可以查看它,而且我的代码更加精简。'过期'实际上只是memcached,只要它认为它已满,最终会清除最早的数据。 – 2010-10-25 22:57:22

+1

现在,我已经拥有了这个伟大的工作,即使在达利也是如此。有一个关于dalli github问题票的评论,最近修改了元帅数据的问题。感谢你的帮助,威廉。 – 2010-10-27 04:14:06