设为首页 收藏本站
查看: 899|回复: 0

[经验分享] Memcached学习笔记(3)一Memcached分布式之spymemcached实现

[复制链接]

尚未签到

发表于 2015-9-1 09:22:46 | 显示全部楼层 |阅读模式
一、Java Memcached 客户端
Memcached的客户端目前有3种:
(1)Memcached Client for Java
(2)SpyMemcached
(3)XMemcached
市面上给这三个做了一个比较:
Memcached Client for Java 比 SpyMemcached更稳定、更早、更广泛;
SpyMemcached 比 Memcached Client for Java更高效;
XMemcached 比 SpyMemcache并发效果更好。
当然了,仁者见仁智者见智了。

二、spymemcached用hash一致性算法实现分布式

spymemcached的MemcachedClient类提供了一系列方法如:get,set,add存取对象。这里我就不做过多的阐述了,可以参见官网的API。
上一篇Memcached学习笔记(2)一Memcached分布式介绍过,要实现Memcached的分布式,关键在于客户端分配存储元素到服务器上的算法,比较好的一种算法像“一致性hash算法”,
下面我将用一段简单的代码阐述下此算法的实现思路。
首先:假定我们有五台服务器IP端口如下:
10.10.224.101:11211
10.10.224.102:11211
10.10.224.103:11211
10.10.224.104:11211
10.10.224.102:11211



    private List<String> cacheServerAddress;//Memcached服务器地址
private TreeMap<Long, MemcachedClient> memcachedClientMap;//构建MemcachedClient对象map
private List<MemcachedClient> memcachedClients;
private int numReps = 160;//每个Memcached服务器节点生成的虚拟节点

定义了几个变量,cacheServerAddress存放如上的ip地址信息,
memcachedClientMap为hash一致性算法根据这五台机器构建的
MemcachedClient的treemap
numReps 定义了一个服务器节点生成的虚拟节点数.

第一步:构建由如上五台服务器组成的memcachedClientMap,每个服务器节点产生160个虚拟节点,相当于说由160个key对应同一台memcached服务器。
代码如下:



    /**
* 设置Memcached客户端
*/
private void setMemcachedClients() {
try {
//根据memcached客户端地址,采用一致性hash算法配置客户端路由,构建一个<key, MemcachedClient>的map
if(cacheServerAddress != null && cacheServerAddress.size() > 0) {
MemcachedClient client = null;
memcachedClients = new ArrayList();
memcachedClientMap = new TreeMap<Long, MemcachedClient>();
for(String address : cacheServerAddress) {
client = createMemcachedClient(address);
if(client == null) {
log.error("setMemcachedClients error address:"+address);
return;
}
memcachedClients.add(client);
for(int i=0; i<numReps / 4; i++) {
//getKeyForNode方法为这组虚拟结点得到惟一名称
byte[] digest= DefaultHashAlgorithm.computeMd5(getKeyForMemcachedClient(address, i));
/**
* Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,
分别对应一个虚拟结点,把虚拟结点四个划分一组的原因*/
for(int h=0; h<4; h++) {
Long k = ((long) (digest[3 + h * 4] & 0xFF) << 24)
| ((long) (digest[2 + h * 4] & 0xFF) << 16)
| ((long) (digest[1 + h * 4] & 0xFF) << 8)
| (digest[h * 4] & 0xFF);
memcachedClientMap.put(k, client);
}
}
}
}
}catch (Exception e) {
log.error("setMemcachedClients error :"+e);
}
}

第二步:构建完服务器后,对于需要存储的元素,如何平均分配到以上服务器中。
传一个参数key唯一标示对象的字符串,得到他的hash值,代码如下:



    private long hash(String key) {
long rv = 0;
byte[] bKey = DefaultHashAlgorithm.computeMd5(key);
rv = ((long) (bKey[3] & 0xFF) << 24)
| ((long) (bKey[2] & 0xFF) << 16)
| ((long) (bKey[1] & 0xFF) << 8)
| (bKey[0] & 0xFF);
return rv & 0xffffffffL; /* Truncate to 32-bits */
}

返回treemap中大于或等于此hash值的key对应的MemcachedClient,即顺时针方向找到离他最近的节点,代码如下:



    private MemcachedClient getMemcachedClientForKey(long hash) {
final MemcachedClient client;
if (!memcachedClientMap.containsKey(hash)) {
//tailMap(key):返回treemap中大于或等于key的对象构建的map
SortedMap<Long, MemcachedClient> tailMap = memcachedClientMap.tailMap(hash);
if(tailMap == null) {
hash = memcachedClientMap.firstKey();
}else {
hash = tailMap.firstKey();
}
//在JDK1.6中,ceilingKey方法可以返回大于或等于且离它最近的那个key
//            Long key = memcachedClientMap.ceilingKey(hash);
//            if(key == null) {
//                hash = memcachedClientMap.firstKey();
//            }else {
//                hash = key;
//            }
        }
client = memcachedClientMap.get(hash);
return client;
}
  这样通过hash一致性算法构建的客户端路由可以将对象平均的分配到不同的服务器。添加或删除一个节点服务器,影响都不大。
  


  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-108183-1-1.html 上篇帖子: memcached 学习 1—— memcached+spring配置 下篇帖子: php分布式缓存系统 Memcached 入门
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表