我正在向一个同时具有登录用户和匿名用户的Rails3站点添加片段缓存,并且需要根据整个站点中显示的内容被更新的时间来控制页面的某些部分何时过期。在这个过程中,我发现memcached不支持expire_fragment的正则表达式,所以现在我正在寻找解决这个问题的方法。
对于匿名用户来说,这不是一个大问题。我创建了类似于‘frontpage- new - Show’或‘schedule- week -forecast-10/24/10’之类的缓存键,并在show模型中创建了新条目时,或者当下周内播出的节目通过清理器进行了修改时,将它们过期。这很好用。
我的问题在于登录的用户。他们每个人都有自己的定制时间表,所以我的密钥看起来像' schedule -user- jschuur -10/10/24‘,其中jschuur是账户的用户名。我理解基于日期的约定,它们自然会过期,但我也希望在当天(或一周)的日程表中发生与show相关的更改时,显式地终止缓存日程表的所有片段。
事实证明,memcached不能完成我这里需要的那种通配符过期(schedule-user-.*-10/10/24)。这意味着我需要某种解决方案,将所有在memcached中的中央查找键中发布的键存储在memcached中,或者让Rails/Ruby以某种方式基于我发送给memcached的键在内部执行此操作。
我假设前者是更好的解决方案。我的问题是,如何以最有效的方式做到这一点,这样我就不会把节省下来的所有时间都浪费在不再访问数据库上了。我可以只在memcached中存储一个数组或散列,检索整个内容,循环if for matches,删除它们并将散列存储回去。这听起来可能适合几百甚至一千个用户,但这真的是最好的方法吗?
有没有人已经解决了这个问题并发布了解决方案?
需要考虑的一件事是,我目前几乎所有的缓存都是通过视图中的语句完成的,面向尚未触发的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作为客户端。
发布于 2010-10-26 01:16:18
EDIT:在用dalli gem编写的时候有一些问题,读操作会导致“编组数据太短”或“memcache中的无效编组数据”。不确定它是否也适用于您。
虽然有点老生常谈,但您可以使用名称空间,然后增加名称空间,从而使使用它创建的所有键无效。为此,首先使用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搜索,然后在缓存名称空间递增时更新此变量。
祝你好运,我希望这对你有帮助。
https://stackoverflow.com/questions/4013763
复制相似问题