客户端实现多个Memcached服务集群

客户端实现多个Memcached服务集群

Memcached服务器之间是独立的,没有任何关联,不能进行集群,Memcached集群是从客户端实现的。

应用系统使用统一的访问Memcached配置,在调用client包来set(key,value), get(key)时,使用相同选取服务器节点的算法,这样就实现了取到先前存入的对象。

选取服务器节点的算法思路是key的哈希值与节点数取模,比如,有Memcached服务器n0,n1,n2,n3,n4,key为"user_name",那么就是 hash(username)%5,如果结果为0就选取n0,依次类推。

选取服务器接点的算法一般封装在memcached client包中。


MemcachedSession session = (MemcachedSession) this.findSessionByKey(msg .getKey());

//默认使用这个会话定位器
private MemcachedSessionLocator sessionLocator = new ArrayMemcachedSessionLocator();

// 使用一致性哈希算法(Consistent Hash Strategy) 建议使用。
builder.setSessionLocator(new KetamaMemcachedSessionLocator());




ArrayMemcachedSessionLocator:


public final long getHash(int size, String key) {
long hash = this.hashAlgorighm.hash(key);
return hash % size;
}

public final Session getSessionByKey(final String key) {
if (this.sessions == null || this.sessions.size() == 0) {
return null;
}
// Copy on read
List<List<Session>> sessionList = this.sessions;
int size = sessionList.size();
if (size == 0) {
return null;
}
long start = this.getHash(size, key);
List<Session> sessions = sessionList.get((int) start);
Session session = getRandomSession(sessions);

// If it is not failure mode,get next available session
if (!this.failureMode && (session == null || session.isClosed())) {
long next = this.getNext(size, start);
while ((session == null || session.isClosed()) && next != start) {
sessions = sessionList.get((int) next);
next = this.getNext(size, next);
session = getRandomSession(sessions);
}
}
return session;
}



KetamaMemcachedSessionLocator:

public final Session getSessionByKey(final String key) {
if (this.ketamaSessions == null || this.ketamaSessions.size() == 0) {
return null;
}
long hash = this.hashAlg.hash(key);
Session rv = this.getSessionByHash(hash);
int tries = 0;
while (!this.failureMode && (rv == null || rv.isClosed())
&& tries++ < this.maxTries) {
hash = this.nextHash(hash, key, tries);
rv = this.getSessionByHash(hash);
}
return rv;
}

public final Session getSessionByHash(final long hash) {
TreeMap<Long, List<Session>> sessionMap = this.ketamaSessions;
if (sessionMap.size() == 0) {
return null;
}
Long resultHash = hash;
if (!sessionMap.containsKey(hash)) {
// Java 1.6 adds a ceilingKey method, but xmemcached is compatible
// with jdk5,So use tailMap method to do this.
SortedMap<Long, List<Session>> tailMap = sessionMap.tailMap(hash);
if (tailMap.isEmpty()) {
resultHash = sessionMap.firstKey();
} else {
resultHash = tailMap.firstKey();
}
}
//
// if (!sessionMap.containsKey(resultHash)) {
// resultHash = sessionMap.ceilingKey(resultHash);
// if (resultHash == null && sessionMap.size() > 0) {
// resultHash = sessionMap.firstKey();
// }
// }
List<Session> sessionList = sessionMap.get(resultHash);
if (sessionList == null || sessionList.size() == 0) {
return null;
}
int size = sessionList.size();
return sessionList.get(this.random.nextInt(size));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值