我正在努力将片段缓存添加到已登录和匿名用户的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作为客户端.
编辑:有一些问题与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搜索以创建缓存键,然后在执行缓存命名空间增量时更新此变量.
祝你好运,我希望这会有所帮助.