1、和每个memcache server保持多个长连接,效果是减少memcache server保持的连接数量及创建销毁连接的开销。不过,memcache本身就支持大并发连接,这个功能也就没什么特别的说道。
2、支持memcache的binary协议命令,实现请求的转发。
3、和memcache一样,基于libevent的事件驱动来处理IO。
4、支持ketama 的一致性hash算法。
5、支持memcache backup集群,当memcache集群有机器挂了,memagent会将get请求转向memcache backup集群。这个功能对于cache的稳定性要求高的场景下会有用武之地。
就提供的功能而言,memagent是个很简单的东西。对于较大的memcache集群,可以考虑搭一套memagent作为proxy使用。
实现分析
1、我得到memagent版本是0.5。除去一致性hash算法ketama的代码,memagent的代码都在magent.c文件中,代码总行数2000多行。稍微拿出半个晚上,就能把这份代码分析得差不多了。
2、memagent像memcache一样,使用了libevent来驱动状态及处理。Libevent是个很适合于事件驱动(最典型的就是网络 IO事件)的场景。像memagent,对于client端的一个请求,它既要处理client端的网络IO,又要处理server端的网络IO,还有可 能处理back server的网络IO,一个流程下来就触发了多达6、7次的网络IO事件。
3、memagent是单进程单线程程序,因为它的工作主要就是接受请求、对请求稍作解析后转发请求,所以逻辑上较为简单,最多的也就是内存拷贝工作,采用单进程单线程也就足够了。
4、memagent的事件回调函数分别是server_accept、drive_client、 drive_memcached_server、drive_backup_server。这4个回调函数的功能也很明显,在drive_client、 drive_memcached_server和drive_backup_server也分别涉及到读写处理的状态机机制,这部分代码涉及到协议解析及 IO处理,代码细节也是琐碎繁杂的很。 基本的过程是:
1)memagent解析出client端的数据(主要是命令类型和key),向映射到的memcache server发送数据,如果memcache server连接不上,memagent会向backup集群(如果设置的话)发送数据。
2)在得到memcache server返回的数据后,memagent还是需要解析,如果这段时间memcache server返回失败,memagent还会再向backup集群请求数据。
3)最后,memagent将数据返回给client。
5、对于backup集群,如果配置了,memagent每次提交操作都会发给backup集群。在get某个memcache server失败时会将向backup集群再请求一遍。
6、对于gets命令,memagent对批量的每个key是单独和memcache server交互的。这块我觉得还可优化,可以合并映射到同一个memcache server的key在发往server的一个请求中批量处理。
7、无论是读client数据还是读server端数据,memagent都是不知道这个请求中到底有多少字节的数据,所以读时首先调用 ioctl(fd, FIONREAD, &toread)函数计算出IO buffer中已经收到的网络字节数据,再对收到的数据做分析确定是否需要继续read。这个技巧在不知道数据包头大小的情况下采用的手段。
8、再说一个实现的小细节。对于event_set的回调函数原型,对于不使用的参数可以通过调用宏#define UNUSED(x) ( (void)(x) )来解决gcc在开-Wall时的报错,我之前看到有文章说是用#pragma也行,不过我没试成功
一致性hash算法
对于memcache客户端就Cache key映射到哪个memcache server的选择算法,最简单的莫过于根据key计算出的hash值取count(memcache server)的余数。对于小的memcache集群或者cache集群整体挂掉不会对服务产生严重影响的情况,这种映射方法就简单实用。
当然,更好的选择是一致性hash算法。该算法的效果是减少或增加一个memcache节点,只会影响到整个集群的1/n的数据。在实现方法上,主要有两种:
1、将memcache物理节点均匀地分布在整数范围构成的hash环。当增加一个节点时,可以将该节点插入环上的两个节点之间,这样只会失效 1/2n的数据,但会使hash环变得不均衡;另一种方法是,重新分布memcache节点在hash环的位置,这样每个节点的数据都会有些缺失,但缺失 的总和是一个节点的数据范围。
2、引入虚拟节点的思想,将一个memcache物理节点散落在hash环上的多个虚拟节点,这在均衡性方法效果会更好些。当然,查找的算法复杂度也由O(1)提高到log(N)。Ketama 算法是实现这个思想的第一个也是用得很多的实现,可以从
[url]http://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients [/url]
得到这个算法的多语言版本实现。
Memagent使用的一致性hash算法实现就是Ketama,但Memagent在代码方面做了简化修改。Ketama的两个核心数据结构是:
struct dot {
unsigned int point;// unsigned int范围内的某个点
int srvid;//memcache server id
};
struct ketama {
unsigned int numpoints;// 一致性hash的虚拟节点数
struct dot *dot;//一致性hash的虚拟节点列表
int count;//memcache server个数
char **name;// 各memcache server名称数组
int *weight;// 各memcache server权重,实际都是一样的
int totalweight;//权重总和
};
struct dot结构表示hash环上一个虚拟节点,struct ketama是算法的全局性数据结构。Ketama 算法涉及到两个函数是:
int create_ketama(struct ketama *ring, int step)
Ring由Memagent之前根据memcache server集群信息构造而来,step取值为500,函数内部再乘以4,表示一个memcache server在hash环上有2000个虚拟节点。
计算虚拟节点的取值及对应的server id的方法如下:
for (i = 0; i < ring->count; i ++) {
pct = (float) ring->weight[i] / (float) ring->totalweight;
ks = (int) floorf(pct * step *(float) ring->count); /* divide by 4 for 4 part */
for (k = 0; k < ks; k ++) {
snprintf(temp, 255, "%s-%d", ring->name[i], k);
ketama_md5_digest(temp, digest);
for (h = 0; h < 4; h ++) {
dot[cont].point = ( digest[3+h*4] << 24 ) | ( digest[2+h*4] << 16 )
| ( digest[1+h*4] << 8 ) | digest[h*4];
dot[cont].srvid = i;
cont ++;
}
}
}
最后会对得到的dot列表针对point大小做排序处理,以便get_server时的二分查找。
源码copy to clipboard打印?
int get_server(struct ketama *, const char *);
int get_server(struct ketama *, const char *);这个函数就是根据key从struct ketama结构中找到对应的memcache server index。Cache key的hash值计算使用的是16位的md5算法。根据key的hash值查找对应在hash环上的位置,采用的是二分查找。
小结
如果你只想要个简单实用的memcache proxy,memagent是个不错的选择。当然,memcache proxy可以做的工作也可以更多,就像另一个memcache proxy实现moxi(http://labs.northscale.com/moxi/)提供了更为丰富的功能,我会在接下来的文章中继续介绍moxi。
转帖自:
http://www.kafka0102.com/2010/01/9.html
分享到:
相关推荐
文件中包含MemCache和Redis的jar包、下载的exe文件以及相关介绍和配置!
Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力
Memcache就不用多介绍了,做开发的人都知道。 但要用得好,却并不是那么容易的事。 如果用得不好,反而得不偿失。 这篇文档短小精悍,囊括了使用过程中需要要注意的方方面面。值得一读。
memcache1.2.8源码分析 压缩包里有带注释的1.2.8的源码 有分析的ppt 有整理的网络上对memcache分析比较好的word文档
Memcache的内存分配机制分析及优化策略的设计,张宏,于琳琳,本文介绍了Memcache软件在Linux下的内存分配机制-Slab内存分配器,并对该机制进行了分析,通过对比不同参数下该分配机制的性能特点, �
Java开发中的Memcache原理及实现
memcache 监控工具,可以实现实时对内存中的memcache进行监控 获取值等等
memcache图形监控工具phpmemcache,尽是一个PHP文件就可以实现对memcache的监控。 使用方法:本地测试监控机安装Apache或者下载XAMPP(Apache+MySQL+PHP+PERL),安装后把memcachephp.zip中的memcache.php文件放到...
windows下memcache安装包 附带php扩展包
最新windows的memcache模块下载 这个模块是平和php5.3的,在我的windowsxp php5.3.5上安装成功 里面有两个php库,一个php_memcache.dll.vc6 和一个php_memcache.dll.vc9 另外一个windows的memcache.exe文件,都是网上...
memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问。
MemCache.0.2.0.zip Memcached Client for Delphi 客户端调用类 MemCache.0.2.0.zip Show all LinksExternal links Memcached Project This project is a delphi unit which implements a thread safe client for ...
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从...
C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档
windows memcache 安装服务,php_memcache.dll所有版本扩展dll 安装说明 在命令行下安装Memcache,输入 ‘c:/memcached/memcached.exe -d install’。 3.启动Memcache,再输入: ‘c:/memcached/memcached.exe -d ...
php的memcache扩展,linux下的,php的memcache扩展分为两种,一种是memcache,一种是基于libmemcached的memcached,这个是memcache版本的beta版本
PHP 添加 Memcache 扩展 : 下载包中包括如下: php_memcache-3.0.8-5.5-nts-vc11-x64.zip php_memcache-3.0.8-5.5-nts-vc11-x86.zip php_memcache-3.0.8-5.5-ts-vc11-x64.zip ...
linux平台使用的memcache压缩包,解压缩之后运行make && make install安装, 然后/usr/local/memcache/bin/memcache -d -m 1024 -u root -p 11211 -c 1024命令运行memcache
$memcache = new Memcache; $memcache->connect("localhost",11211); echo "Server's version: " . $memcache->getVersion() . "\n"; $tmp_object = new stdClass; $tmp_object->str_attr = "test"; $tmp_object->...