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缓存介绍** 在IT行业中,缓存技术是提高系统性能和响应速度的关键因素之一。MemCache和Redis是两种广泛使用的分布式内存缓存系统,它们能够有效地存储和检索数据,减轻数据库的负担,提升应用的...
标题"memcache1.2.1 for windows"指的是Memcache的1.2.1版本,这是专为Windows操作系统设计的一个内存缓存系统。Memcache是一个广泛使用的开源高性能分布式内存对象缓存系统,它能够通过在内存中存储数据来减少对...
**Memcache 深度解析** Memcache 是一个高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,...同时,对于有兴趣的开发者,源码分析和工具使用将进一步加深对Memcache的理解,使其在实际工作中发挥更大作用。
3. **具体工具介绍** - **mcmon**:一个简单的命令行工具,提供实时查看Memcached服务器的状态,如命中率、内存使用、当前连接等。 - **memcached-top**:类似于`top`命令,提供实时的动态视图,显示每个Memcached...
本文将详细介绍如何安装配置Memcache,并提供基本的操作示例。 #### 二、安装与配置 ##### 1. 检查已安装状态 在安装Memcache之前,首先需要确认系统中是否已经安装了Memcache。可以通过命令行工具检查端口使用...
**memcache1.2.8源码分析** Memcache是一款广泛应用的开源分布式内存对象缓存系统,用于在应用服务器之间共享数据,以减轻数据库的负载。它的主要特点是高性能、轻量级以及简单易用。本篇文章将深入探讨memcache...
**Memcache Win版服务器与.NET驱动详解** Memcache是一款高性能的分布式内存缓存...对于.NET开发者来说,理解如何在Windows环境中配置和使用Memcache,以及选择合适的.NET客户端库,是提升应用性能的关键技能之一。
memcache是广泛应用于Web开发中的一个内存对象缓存系统,它能够提高网站性能,通过将数据存储在内存中,减少对数据库的访问,从而加快数据读取速度。 PHP的memcache扩展允许开发者在PHP应用程序中与memcached服务器...
通过以上介绍,我们可以了解到PHP Memcache多版本拓展库在PHP7及更高版本中的应用和配置方法。它不仅提供了广泛的环境兼容性,还为开发者带来了高效、便捷的Memcached操作方式。在实际项目中合理利用此拓展,能够...
2.1 **文档目的**:阐述该文档的主要意图,即介绍MemCache的基础知识、预研目标及已取得的成果,帮助读者理解MemCache在实际应用中的价值和实施步骤。 2.2 **阅读对象**:面向的是IT开发者、系统管理员和对分布式...
Memcache 是一种广泛使用的分布式内存缓存系统,用于在 Web 应用程序中提高数据读取速度,通过存储经常访问的数据到内存中,避免了频繁的数据库查询,从而提升了整体性能。 描述中的“实测可以使用”意味着这个 ...
本文将详细介绍在Windows上安装Memcache的步骤,并提供相关安装包的信息。 首先,了解Memcache是什么至关重要。Memcache是一种高性能的分布式内存对象缓存系统,它可以用来存储数据,如数据库查询结果、session数据...
针对Memcache的安装与配置,以及如何在PHP中调用Memcache,本文提供了两个视频教程的链接,分别介绍了安装配置的全过程和PHP调用方法的具体操作。这些教程可以作为学习Memcache安装和使用过程中的辅助材料。 综上所...
**PHP之Memcache的使用** Memcache是一种广泛应用于Web开发中的高性能、分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提高网站性能。它通过存储数据到内存中,使得频繁访问的数据能被快速获取,从而...
以下将详细介绍如何在Windows 7环境下安装和使用Memcache。 首先,你需要确保你的计算机上已经安装了PHP环境。这里提到的PHP版本是5.4,这意味着我们需要的是与该版本兼容的Memcache扩展。在给定的文件列表中,`...
Memcache是一种广泛使用的分布式内存对象缓存系统,它可以在服务器集群间通过网络共享小块内存,从而提升应用程序的性能,减少数据库负载。在PHP中,我们通常使用php_memcache.dll扩展来与Memcache服务器进行交互。...
"PHP实现多服务器session共享之memcache共享"的主题着重于如何在多台服务器之间有效地存储和同步用户的session数据,以确保用户在不同服务器间的会话状态能够保持一致。本文将深入探讨这一主题,并围绕相关知识点...