#enum_memcache_keys.rb:
require 'rubygems'
require 'socket'
class EnumMemcacheKeys
MEMCACHE_STATS = ["END", "OK", "DELETE", "ERROR"]
class << self
def open(host, port)
s = TCPSocket.open host, port
yield s if block_given?
ensure
s.close if s
end
def items(host = 'localhost', port = '11211')
i = []
open(host, port) do |s|
s.send("stats items\r\n", 0)
until MEMCACHE_STATS.include?(line = s.gets.strip) do
i << line
end
end
i
end
def keys(host = 'localhost', port = '11211')
keys = []
open(host, port) do |s|
buff = items(host, port)
items = []
buff.each { |b| items << b.split(':')[1] }
keys = []
items.each do |i|
s.send("stats cachedump #{i} 0\r\n", 0)
until MEMCACHE_STATS.include?(line = s.gets.strip) do
keys << line.split(' ')[1]
end
end
end
keys
end
protected :open
end
end
#use
p EnumMemcacheKeys.items
p EnumMemcacheKeys.keys('10.0.0.5', '11211')
今天把rails上memcached实验做了
实验说明:
1.memcache server共有3台, 平台都为Linux
2.rails应用运行在一台windows上
cached_model
memcached源码包的安装就不多说明了,以前的日志中有, rails的插件主要用了cached_model和cache_fu
因为感觉cached_model功能没有cache_fu完善和灵活,所以这里对cached_model就不多说,只提几点:
a)在environment.rb中添加:
require 'memcache'
require 'cached_model'
memcache_options = {
:c_threshold => 10_000,
:compression => true,
:debug => false,
:namespace => 'rails_production',
:readonly => false,
:urlencode => false
}
CACHE = MemCache.new memcache_options
CACHE.servers = ['192.168.1.12:11211'] #memcache的缓存节点地址和端口
b)在要启用memcache的模型中将模型的继承改为:
Model < CachedModel
这样基本的功能就有了,cached_model其实重写了模型的find方法,在查询缓存时会自动将数据存入缓存,当然要注意设置缓存过期等,cached_model不多说了
cache_fu
cache_fu是acts_as_cached的完善版,所以在模型的配置中也用的是acts_as_cached,使用:
a)安装插件后,将cache_fu/defaults/memcached.yml.default复制到config/下面,重命名为memcached.yml
b)配置文件memcached.yml,该文件分为4大部分,defaults部分为全局参数的默认配置,下面的三部分对应的就是三种运行环境的特殊设置,这里只说明一个参数就是raise_errors, 它的默认值为true, 这样会导致当一台memcache server down掉的时候页面抛出异常,很不友好,所以推荐把该值设置为false, 这样当一台server down掉时系统将正常运作,只是会重新查询数据库或者启用另一台server, 而这也正是我们需要的
c)在模型中加入
acts_as_cached
具体的参数见文件lib/cache_methods.rb文件, 或者README
d)使用时只用
Model.get_cache(id)就可以了,也可以存储复杂的原型以及关联查询:
class Child < ActiveRecord::Base
acts_as_cached :ttl => 15.minutes #自动失效时间
belongs_to :parent
def parent
Parent.get_cache(self.parent_id)
end
end
get_cache方法会自动去差村缓存对象,如果没有该对象的缓存数据将会重新查询并放入memcache
设置缓存过期钩子
def after_save
expire_cache(id)
end
当然还要设置after_update等
设置belongs_to关联
class Story < ActiveRecord::Base
acts_as_cached :include => :author
belongs_to :author
def after_save
expire_cache(id)
end
end
也可以这样:
class Story < ActiveRecord::Base
acts_as_cached
belongs_to :author
def author
Author.get_cache(author_id)
end
def after_save
expire_cache(id)
end
end
更容易理解
设置has_many关联
class Author < ActiveRecord::Base
acts_as_cached
has_many :stories
def after_save
expire_cache(id)
stories.each do |story|
story.expire_cache
end
end
end
注意:
1. 以上所有都必须开启缓存,即 config.action_controller.perform_caching = true;
2. 在启动时要注意先启动所有的cache server, 然后是rails应用的server, 否则会有500错误
3. 有一个gem memcache_client_stats, 是专门用来监控cache server的,好像不错,还有对应监控工具cacti的模板,很强大!
4. 又发现一个gem mem_cache_fragment_store, 专门结合memcached来实现片段缓存的, 很强大,有时间在研究.
ps:cache_fu从源代码可以看出好像集成了fragment cache的功能,再研究研究吧
<完>
继续学习memcached:(下面大部分是我从网上看来总结的)
A.一定要记着,memcached是缓存,所以不会永久保存在机器上,重启就没了
B. memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空 间不足时,就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。
不过,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“-M”参数可以禁止LRU,如下所示:
$ memcached -M -m 1024
启动时必须注意的是,小写的“-m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。
指定“-M”参数启动后,内存用尽时memcached会返回错误。话说回来,memcached毕竟不是存储器,而是缓存,所以推荐使用LRU。
C. 上面说的是memcached的一种缓存控制,另一种就是memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过 期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。就是以检查记录的时间戳来看数据是 否过期,这个过期时间是可以人为控制的
D.memcached的分布式
memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。至于memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。
memcached的分布式是什么意思?
这里多次使用了“分布式”这个词,但并未做详细解释。现在开始简单地介绍一下其原理,各个客户端的实现基本相同。
下面假设memcached服务器有node1~node3三台,应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据。
首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。
同样,“kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。
接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。
这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。 memcached服务器增多后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。
不通的客户端语言都有对应的分布式调用方法
E.下面放上一篇实际应用的文章,小日本的..应用
1.安装memcached
要求:我的测试平台为RHEL AS4U4, 安装钱要确认是否安装了libevent和libevent-devel rpm, 可以去DAG下载,平台的对应版本要正确。
memcached-1.2.6.tar.gz去官方下载
安装:安装为标准的编译安装方式,./configure; make; make install 即可
启动为memcached -p port -m 2048m -d; 指定端口和内存的占用,以后台的方式运行,详细的查看help
2.安装memcache-client gem
安 装前先要安装依赖的gem,有ZenTest, hoe, rubyforge, 其中rubyforge这个gem在rubyforge.org上没法搜索到,而且使用gem install rubyforge的安装方式也老是报错,在英文版的google里多搜搜就行了
现在在ruby下已经可以使用这个gem了,使用前要require 'memcache';, 可以查看ri MemCache
3.安装rails的插件
现 在rails结合memcached的插件有acts_as_cached, cache_fu, cache_model, 其中cache_fu是acts_as_cached的加强版,所以推荐使用cache_fu,安装使用ruby script/plugin就行了
cache_fu的使用比较简单,可以看下插件下的README,或者google下,具体的使用再慢慢研究....
开始搞rails的memcache的了,
几个概念:
1.memcached是一个开源项目,提供高性能的分布式缓存集群
2.大多数的开发语言都有对应的访问memcached的客户端接口
3.现在已经有了memcached结合数据库的工具,如memcachedb,memcache_engine;其中memcache_engine是专门对应MySQL的缓存引擎
4.memcache-client gem和memcache gem是两个对应ruby的memcached的接口,其中memcache gem是最新的,据说速度比memcache-client快150倍,但可能还不成熟
5.cache_fu(即acts_as_cached)是rails的结合memcached的插件,可以方便的控制数据库的查询缓存
好了几本的概念说完了,下面就贴一点网站找来的文章吧...
-----------------------------------------shitou的分割线-------------------------------------
缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。
Memcached是什么?
Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。
Memcached能缓存什么?
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
Memcached快么?
非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)来均衡任何数量的打开链接,使用非阻塞的网络I/O, 对内部对象实现引用计数(因此,针对多样的客户端,对象可以处在多样的状态), 使用自己的页块分配器和哈希表, 因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。
Danga Interactive为提升Danga Interactive的速度研发了Memcached。目前,LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。而这 些,是由一个由web服务器和数据库服务器组成的集群完成的。Memcached几乎完全放弃了任何数据都从数据库读取的方式,同时,它还缩短了用户查看 页面的速度、更好的资源分配方式,以及Memcache失效时对数据库的访问速度。
Memcached的特点
Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。
-----------------------------------------shitou的分割线-------------------------------------
libmemcached是一个基于C/C++实现的memcached client library,memcached gem给这个library提供了ruby封装,根据原作者的性能评测,它比目前常用的memcache-client gem最多要快150倍。
因为对memcache的操作在rails处理整个http请求中所占时间比例并不多,而且JavaEye网站大部分是做cache读取操作,于是做了2个试验测试一下2者对于提升整个网站的性能到底有多少帮助:
1. 测试访问JavaEye网站的首页,在这个请求中只有一个缓存读取操作,使用ab简单地跑单次请求10000次:
使用memcache-client,平均完成每个请求是9.247 ms
使用memcached,平均完成每个请求是8.982 ms
对于整体性能提升在3%左右
2. 测试访问某个论坛版面的页面,整个请求有超过60次的缓存读取操作,使用ab简单跑单次请求1000次:
使用memcache-client,平均完成每个请求是95.872 ms
使用memcached,平均完成每个请求是91.591 ms
对于整体性能提升在5%左右
从试验可以看出,对于整体性能还是有一定提高的。JavaEye用的cache插件是cache_fu,它只支持memcache-client,不过通过简单的修改就可以支持这个新gem,我提交了一个补丁,有兴趣的话可以从这里下载到补丁。
--分割线--
cache_fu的作者已经将这个补丁添加到代码树,可以从github checkout: http://github.com/defunkt/cache_fu/tree/master
-----------------------------------------shitou的分割线-------------------------------------
memcachedb是 一个由新浪网的开发人员开放出来的开源项目,给memcached分布式缓存服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制,让memcached具备了事务恢复能力、持久化能力和分布式复制能力,非常适合于需要超高性能读写速度,但是 不需要严格事务约束,能够被持久化保存的应用场景,例如memcachedb被应用在新浪博客上面。
memcachedb给 memcached添加了一些数据库才具备的特性,但是我们还不能说memcachedb已经是一个数据库了,这是因为 memcached不支持内存对象的遍历操作,当然更加不能支持复杂的查询操作,只能支持根据已知的key去查询对应的value。因此如果想把 memcachedb当成一个高性能的分布式内存数据库来使用的话,查询的问题就没有办法解决,只能在应用程序里面配合其他方案做一些折衷。
然而memcached的另外一个开源项目完美的填补了这一个缺陷,就是memcache_engine。
memcache_engine 是一个MySQL数据库的存储引擎,目前只支持MySQL5.1数据库,他能够把memcachedb作为 MySQL数据库的一个存储引擎和MySQL集成起来,让用户通过标准的SQL查询语句访问memcachedb中存放的数据,请看如下示例:
CREATE TABLE `a` ( `a` int(11) NOT NULL DEFAULT '0', `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`) ) ENGINE=MEMCACHE DEFAULT CHARSET=latin1 CONNECTION='localhost:6666\;localhost:6688';
创 建表a,存放在分布式memcached server:localhost:6666和localhost:6688当中。然后我们就可以使用标准的SQL语句随意的进行CRUD操作去使用 memcachedb了,这实在是太酷了!有了memcache_engine,我们就可以用SQL去访问memcached,有了 memcachedb,我们就不必担心数据丢失问题,事务恢复问题了,简直是绝配,让memcached真正成为了一个高性能的分布式数据库系统了。目前 memcache_engine项目还是早期试验阶段,让我们期待memcache_engine项目早日发布正式版本吧!
顺便多说几句:最近一年来,特别是最近一个月以来,围绕memcached的开源项目发展的非常非常活跃:
1、最近刚刚发布了memcached的新的高性能C客户端接口: libmemcached
2、由于有了libmemcached,该组织又发布了memcache_engine存储引擎,cool!
3、由于libmemcached的发布,不到一周时间,ruby的两个崭新的memcache client就问世了,他们是Caffeine和New memcache-client,让ruby访问memcached的速度大幅度提高,请看:libmemcached发布了,ruby访问memcached提速20倍
4、memcachedb发布了,这是中国的互联网公司贡献的开源项目
以 上几个项目都是在2008年1月发布的,真的不是一般的繁荣阿。再加上之前发布的新的支持异步访问的Java Memcached API和C#接口,可以说除了Python,其他主流非主流编程语言都可以使用memcached了。其实即便是Python还没有公布出来的开源接口, 我们也知道国内的web2.0网站豆瓣就是使用Python访问memcached,并且支持了极大的访问量,因此目前围绕memcached的开源项目 发展的情况非常的繁荣。
memcached最近两年这么受欢迎,其实和互联网web2.0的流行有很大的关系,web2.0网站通 常需要个性化页面,依赖于页面局部和数 据细颗粒度的缓存来提升性能,并且web2.0网站流量都很大,因此memcached这种高性能分布式缓存服务器就大行其道了。
当然我觉得最具有革命意义的还是memcache_engine和memcachedb这两个项目的发布,他们能够让memcached的用途不仅仅限于缓存服务器而已,而是能够真正充当分布式数据库来使用了,这无异是诸多大流量web2.0网站和开发人员的福音阿。
-----------------------------------------shitou的分割线-------------------------------------
放一个链接http://tech.idv2.com/2008/07/10/memcached-001/, 这个介绍的比较详细

just DO NOT support IE