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[getServerForKey(k)];
    }
    
    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服务器就可以了。

 

 

 

 

posted on 2012-09-27 18:18  若风尘  阅读(459)  评论(0编辑  收藏  举报

导航