Redis服务器配置

来源:互联网 发布:cgwang插画网络 编辑:程序博客网 时间:2024/05/01 02:41

因为项目需求,需要为Rails view添加cache。首先我们来说说Rails常用的cache方法:

Rails的Cache分四种: 

1,Page Cache - Fastest 
2,Action Cache - Next Fastest 
3,Fragment Cache - Least Fastest 
4,ActiveRecord Cache - Only available in Edge Rails 


1. 页面缓存

开发时使用page cache首先要设置好config/environments/development.rb: 

  1. config.action_controller.perform_caching = true  

而production环境下默认是开启cache功能的 
Page Cache是Rails中最快的cache机制,使用Page Cache的前提一般为: 
1,需要cache的page对所有用户一致 
2,需要cache的page对public可访问,不需要authentication 

在你的controller中添加 caches_page :"action_name" 。 这种cache速度快,可以节省很多时间,但是所有的visitor都能看到你的data,无需验证。

至于清除缓存,可以使用sweeper。首先编辑config/environment.rb: 

Java代码  收藏代码
  1. Rails::Initializer.run do |config|  
  2.   # ...  
  3.   config.load_paths += %w(#{RAILS_ROOT}/app/sweepers)  
  4.   # ...  

这告诉Rails加载#{RAILS_ROOT}/app/sweepers目录下的文件 
我们为BlogController定义app/sweepers/blog_sweeper.rb: 
Java代码  收藏代码
  1. class BlogSweeper < ActionController::Caching::Sweeper  
  2.   observe Post # This sweeper is going to keep an eye on the Post model  
  3.   
  4.   # If our sweeper detects that a Post was created call this  
  5.   def after_create(post)  
  6.     expire_cache_for(post)  
  7.   end  
  8.   
  9.   # If our sweeper detects that a Post was updated call this  
  10.   def after_update(post)  
  11.     expire_cache_for(post)  
  12.   end  
  13.   
  14.   # If our sweeper detects that a Post was deletedcall this  
  15.   def after_destroy(post)  
  16.     expire_cache_for(post)  
  17.   end  
  18.   
  19.   private  
  20.   def expire_cache_for(record)  
  21.     # Expire the list page now that we posted a new blog entry  
  22.     expire_page(:controller => 'blog', :action => 'list')  
  23.   
  24.     # Also expire the show page, in case we just edit a  blog entry  
  25.     expire_page(:controller => 'blog', :action => 'show', :id => record.id)  
  26.   end  
  27. end  

然后我们在BlogController里加上该sweeper即可: 
Java代码  收藏代码
  1. class BlogController < ApplicationController  
  2.   caches_page :list, :show  
  3.   cache_sweeper :blog_sweeper, \:only => [:create, :update, :destroy]  
  4.   # ...  
  5. end  

我们可以配置cache的静态html文件的存放位置,这在config/environment.rb里设置: 
Java代码  收藏代码
  1. config.action_controller.page_cache_directory = RAILS_ROOT + "/public/cache/"  

然后我们设置Apache/Lighttpd对于静态html文件render时不接触Rails server即可 
所以Page Cache就是最快的Cache,因为它不与Rails server打交道,直接load静态html。

2. Action Cache

Action Cache相关的helper方法是caches_action和expire_action,其他基本和Page Cache一样 
另外我们还可以运行rake tmp:cache:clear来清空所有的Action Cache和Fragment Cache 

Java代码  收藏代码
  1. class BlogController < ApplicationController  
  2.   before_filter :authentication  
  3.   caches_action :list, :show  
  4.   cache_sweeper :blog_sweeper, \:only => [:create, :update, :destroy]  

如上代码所示,我们将authentication这个filter放在caches_action之前声明,这样我们的Action Cache在执行之前会先访问authentication方法 
这样可以弥补Page Cache不能对需要登录认证的Page进行Cache的缺点 
生成的cache文件为tmp/cache/localhost:3000/blog/list.cache,这样对不同subdomain的访问页面可以cache到不同的目录 
由于每次访问Action Cache时都需要与Rails server打交道,并且要先运行filters,所以比Page Cache的效率稍低 。


3. 片段缓存
这个也是我实际在项目中用到的。首先介绍基本信息:

Fragment Cache用于处理rhtml页面中的部分需要cache的模块,如app/views/blog/list.rhtml: 

Java代码  收藏代码
  1. <strong>My Blog Posts</strong>  
  2. <% cache do %>  
  3.   <ul>  
  4.     <% for post in @posts %>  
  5.       <li><%= link_to post.title, :controller => 'blog', :action => 'show', :id => post %></li>  
  6.     <% end %>  
  7.   </ul>  
  8. <% end %>  

生成的cache文件为/tmp/cache/localhost:3000/blog/list.cache 
我们需要在BlogController的list方法里加上一行判断,如果是读取Fragment Cache,则不必再查询一次数据库: 
Java代码  收藏代码
  1. def list  
  2.   unless read_fragment({})  
  3.     @post = Post.find(:all, \:order => 'created_on desc', :limit => 10)  
  4.   end  
  5. end  

Fragment分页时的Cache: 
Java代码  收藏代码
  1. def list  
  2.   unless read_fragment({:page => params[:page] || 1}) # Add the page param to the cache naming  
  3.     @post_pages@post = paginate :posts, :per_page => 10  
  4.   end  
  5. end  

rhtml页面也需要改写: 
Java代码  收藏代码
  1. <% cache ({:page => params[:page] || 1}) do %>  
  2.   ... All of the html to display the posts ...  
  3. <% end %>  

生成的cahce文件为/tmp/cache/localhost:3000/blog/list.page=1.cache 
从分页的Fragment Cache可以看出,Fragment Cache可以添加类似名字空间的东西,用于区分同一rhtml页面的不同Fragment Cache,如: 
Java代码  收藏代码
  1. cache ("turkey") => "/tmp/cache/turkey.cache"  
  2. cache (:controller => 'blog', :action => 'show', :id => 1) => "/tmp/cache/localhost:3000/blog/show/1.cache"  
  3. cache ("blog/recent_posts") => "/tmp/cache/blog/recent_posts.cache"  
  4. cache ("#{request.host_with_port}/blog/recent_posts") => "/tmp/cache/localhost:3000/blog/recent_posts.cache"  

清除Fragment Cache的例子: 
Java代码  收藏代码
  1. expire_fragment(:controller => 'blog', :action => 'list', :page => 1)  
  2. expire_fragment(%r{blog/list.*})

四、ActiveRecord Cache 
Rails Edge中ActiveRecord已经默认使用SQl Query Cache,对于同一action里面同一sql语句的数据库操作会使用cache 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

重要的在这里!!

在我的项目里片段缓存是和redis服务器配合工作的,关于redis的介绍在我另一篇博客里。这里重点讲他们如何配合使用。我的每个cache都有一个唯一的key来标识,并且设置了过期时间。这里我要强调下key的重要性,如果你key用得好,那么cache的其他参数就不必劳神设置了,这是一个非常聪明,有技巧的东西。