szs 发表于 2015-9-2 05:14:23

Memcached学习笔记(2)一Memcached分布式

memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。服务器只是实现了内存存储的功能,至于memcached的分布式,则是完全由客户端程序库实现的。通过memcached的客户端路由实现memcached集群环境,这种分布式是memcached的最大特点。
客户端做路由
客户端做路由的原理非常简单,应用服务器在每次存取某key的value时,通过某种算法把key映射到某台memcached服务器nodeA上,因此这个key所有操作都在nodeA上,结构图如下所示:
存储某个key-value,客户端程序根据某种算法获得存取此value的服务器,存入该服务器中,如下图:

取某个key-value,根据key,同样的算法获取存取该key对应value的服务器。

因此关键在于算法的选择,最基本的要求就是能让数据平均到所有服务器上。spymemcached是一个用得比较广的java客户端,它就提供了一种简单的hash算法,实现类为ArrayModNodeLocator,从key映射到node的源码如下:



    public MemcachedNode getPrimary(String k) {
return nodes;
}
private int getServerForKey(String key) {
int rv = (int) (hashAlg.hash(key) % nodes.length);
assert rv >= 0 : "Returned negative key for key " + key;
assert rv < nodes.length : "Invalid server number " + rv + " for key "
+ key;
return rv;
}

由上可知所有的note都被放到数组中,通过hash取模的算法获得note数组中的某一个服务器。当添加一个note或删除一个note的时候,找不到对应的note该怎么办,上面的策略是在数据组里顺序向下轮询node,找第一个工作正常的node。很显然这种方式是有问题的,note发生变化了,将导致大量的key找不到其原来所对应的note,从而会重新将值放置到新的note服务器中。如何解决这个问题呢?分布式这块有一个算法“hash一致性算法”可以很好的解决这个问题,关于hash一致性算法,博文分布式设计与开发(二)------几种必须了解的分布式算法 讲的比较细致。spymemcache 的KetamaNodeLocator类就实现了这种算法,源码如下:



public MemcachedNode getPrimary(final String k) {
MemcachedNode rv = getNodeForKey(hashAlg.hash(k));
assert rv != null : "Found no node for key " + k;
return rv;
}
MemcachedNode getNodeForKey(long hash) {
final MemcachedNode rv;
if (!ketamaNodes.containsKey(hash)) {
//tailMap(key):返回treemap中大于或等于key的对象构建的map
SortedMap<Long, MemcachedNode> tailMap = getKetamaNodes().tailMap(hash);
if (tailMap.isEmpty()) {
hash = getKetamaNodes().firstKey();
} else {
hash = tailMap.firstKey();
}
}
rv = getKetamaNodes().get(hash);
return rv;
}

memcached服务端集群
由上面可知一般的应用中memcached服务端集群不用做太多工作,部署一堆memcached服务器就可以了。

  


  
页: [1]
查看完整版本: Memcached学习笔记(2)一Memcached分布式