我正在努力将片段缓存添加到已登录和匿名用户的Rails 3站点,并且需要根据整个站点中显示的内容何时更新来控制页面的某些部分何时到期。中途,我发现memcached不支持expire_fragment的regexp,所以现在我正在寻找方法。
对于匿名用户,这不是一个大问题。我创建缓存键,例如'frontpage-new-shows'或'schedule-weekly-forecast-10/24/10',并在Show模型中创建新条目时使用,或者在下周播出时播放通过扫地机进行修改。这很好用。
我的问题是登录的用户。他们每个人都有自己的自定义时间表,因此我的密钥看起来像'schedule-user-jschuur-10/10/24',其中jschuur是帐户的用户名。我理解,使用基于日期的约定,它们会自然过期,但我也希望在当天(或周)的日程安排中显示相关更改时,明确地使缓存日程表的所有片段到期。
事实证明,memcached不能做我需要的那种通配符到期(schedule-user - 。* - 10/10/24)。这意味着我需要某种解决方案来存储在memcached中的中央查找键中发布的所有密钥,或者让Rails / Ruby在内部根据我发送给memcached的密钥在内部执行此操作。
我认为前者是更好的解决方案。我的问题是,我该如何以最有效的方式做到这一点,所以我不会把所有的时间都打破,而不是再次击中数据库。我可以在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作为客户端。
答案 0 :(得分:5)
编辑:使用dalli gem编写的内容存在一些问题,执行读取操作会导致“编组数据太短”或“memcache中的编组数据无效”。不确定它是否适合你。
虽然有点hackish,但您可以使用命名空间然后增加命名空间,从而使使用它创建的所有密钥无效。为此,首先使用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搜索,然后在执行缓存命名空间增量时更新此变量。