rails缓存学习

阅读更多

 

FORM:http://kenbeit.com/tag/cache

 

http://blog.163.com/zhj_mouse/blog/static/6411853720114432550741/

Rails 自身提供四种缓存方式,即 Page Cache, Action CacheFragment Cache  ActiveRecord Cache 这四种缓存。Page Cache 是最高效的缓存机制,他把整个页面以静态页面 HTML 的形式进行缓存,这对于不会经常发生变化的页面是非常有效的。Action Cache 是对某个 action 进行缓存,与Page Cache 的区别在于:HTTP 请求会经过 Rails 应用服务器,直到所有的 before filters 都被处理,这种缓存就能处理 Page Cache 无法处理的如需要登录验证的页面,可以所验证的步骤加入 before filter 中,Fragment Cache 则为了缓存页面中的某一部分,同一个页面中的不同部分还可以采用不同的过期策略。对于 Rails 本身的缓存机制,我们可以写 sweeper 进行过期和清除的处理。ActiveRecord Cache 则是较新版本 Rails 中新推出的对ActiveRecord 的缓存机制,使用 SQL 查询缓存,对于同一 action 里面同一 SQL 语句的数据库操作会使用缓存。 ——摘自http://www.ibm.com/developerworks/cn/web/1003_yekai_railsarch/

 

 

你可以通过以下几个link中学习如何使用Rails Cache。

 

http://rails-everyday.group.iteye.com/group/wiki/1160-Rails%20Cache

 

http://guides.rubyonrails.org/caching_with_rails.html

 

http://www.cowboycoded.com/2010/07/14/performance-exercise-1-rails-cache-cash/

 

从缓存的速度上来说 Page Cache > Action Cache > Fragment Cache > AR Cache

 

sweeper是观察者模式的应用,通过hook(before_xxx,after_xxx)方法,来触发对的操作缓存,比如设置缓存过期。

 

本博客也刚刚加上了Rails Cache。虽然几乎没有什么访问量,加上了也没感觉出多大的变化,但是作为学习后的简单应用还是不错的。

 

选择使用何种Cache:

 

本博客分左中右布局,左右2边的数据是写在erb中,并非ajax调用,中间是博文。这样就没法使用Page Cache和Action Cache,因为它们会把整个页面全部存下来,那么左右2边的数据都被保存成了html。如果我新发布更新文章用了新的分类和标签,要更新缓存,那么之前被缓存的博文页面都没用了,否则新的分类和标签就显示不出来。因此我选择了Fragment Cache,对favorite,category,tag cloud,archive4个区域还有post主区域都做了Fragment Cache。当我有更新操作时,只要更新相关的那篇post和category,tag cloud,archive的Fragment Cache就行了,其他post的Fragment Cache都不需要更新。这样在访问单篇post时,速度会比不用cache快好多倍,第一不需要查任何数据库,第二页面也被Fragment Cache了,不需要从erb文件再生成html的过程。在log里可以看到所花时间减少了7倍左右,但是由于本来就是在毫秒级别,又没什么访问量,所以实际体验上也没差。(汗。。。

 

 




 

如果把Cache换成Page Cache要怎么做呢?

 

我大概想了下,除了post区域,其他的几块,换成ajax读取,然后那几块的查询的数据可以用Rails.cache缓存起来。这与可以用Page Cache来缓存整个页面,然后通过配置nginx绕过app server直接访问。更新时也只需要更新相关post的Page Cache和查询缓存,其他的post都不需要动。这样速度应该会比前面更快一点。

 

Rails支持的存储策略也有好几种:MemoryStore,FileStore(默认),DRbStore和MemCacheStore(memcached)。再细分还有支持线程安全的SynchronizeMemoryStore和带有GZiP压缩的CompressMemCacheStore。我现在用的是MemCacheStore,其实我这点访问量,这点数据用哪个都没差,我纯粹是想试试memcached。使用哪种策略在实际编码没有太大区别(前提是用rails内置的Cache API)。

 

还有一些gem插件也是用来做memcached缓存的,有cache_fu,cache-money,memcached,我都简单使用了一下。

 

cache_fu是重写acts_as_cached,它github上根本就没有如何使用的教程。我google收到一个,http://www.railsfire.com/article/memcached-and-cache-fu。cache_fu我用下来感觉比较自由,给定cache的key,然后可用通过多种方式做缓存,可以直接User.get_cache(id);也可以给一个block,User.get_cache('users_page_1'){User.paginate :page => 1, :per_page => 10};还可以直接给一个方法的symbol,比如有一个类方法叫daily_hot_users,你可以User.get_cache(:daily_hot_users)。它的缺点有2个,其实算1个,就是不够透明。必须使用它的API方法来对缓存操作,缓存的更新和失效也要人工来控制。不过好在作者还在不断维护,希望以后能更好。

 

cache-money在github上关注度很高,它也是twitter贡献的一个gem。它在github上的列出的用法还是比较详细的。它是一个write-through和read-throught的gem。它的优点是透明化,非侵入式,仍然使用Rails的API,它能自动检测缓存是否存在,从而选择是从memcached中还是数据库中读取数据。同时如果对象被创建,更新或者删除,它会自动更新缓存,保持其一致性。它的缺点是缓存的对象上没有那么自由,应为它是自动处理缓存,所以key是通过指定的字段来生成的,默认是用id,其他的字段的话要在Model里面用index xxx指定一下。因为这样的原因,如果查询中不带有指定字段的条件,就没法做cache。比如User.all和User.first就没办法缓存,但是假设User有role字段,已经用index :role指定,User.find(:all, :conditions => ["role = 'admin'"])就会进行缓存。另外cache-money只支持=和AND,其他比如like,!=,OR操作符,还有Rails中的join和include等,这些都没法缓存。另外cache-money对rails3支持有点小问题,activesupport和active_support的名字问题,这个应该有办法从源码中改掉。但是cache-money本身已经很久没有更新了,不过fork它的人还满多的,不知道能不能找到一个能继续维护它的。

 

memcached是libmemcached的接口,http://www.iteye.com/news/905,这上面说能提速20倍。但是它的API很简单,它只是替换了Rails原来的memcache-client而以,没有和AR结合。

 

你可能感兴趣的:(rails,cache,memcached,activerecord,sql)