从MEMCACHED_DISTRIBUTION_MODULA开始

原创 2013年12月02日 23:17:08

一、修改test程序

本节开始探索分布式算法,使用三个memcached服务器,将test程序修改为const char* server_list = "localhost:11211, localhost:11212, localhost:11213"。对于分布式算法,系统默认为MEMCACHED_DISTRIBUTION_MODULA,见_memcached_init()中self->distribution = MEMCACHED_DISTRIBUTION_MODULA。


二、hashkit_create

memcached_create调用_memcached_init(),其中会调用hashkit_create(&self->hashkit),进而调用_hashkit_init()。

static inline void _hashkit_init(hashkit_st *self)
{
  self->base_hash.function= hashkit_one_at_a_time;
  self->base_hash.context= NULL;

  self->distribution_hash.function= hashkit_one_at_a_time;
  self->distribution_hash.context= NULL;

  self->flags.is_base_same_distributed= true;
}

三、run_distribution

memcached_server_push()中会调用run_distribution()。

memcached_return_t run_distribution(memcached_st *ptr)
{
  if (ptr->flags.use_sort_hosts)
  {
    sort_hosts(ptr);
  }

  switch (ptr->distribution)
  {
  case MEMCACHED_DISTRIBUTION_CONSISTENT:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED:
    return update_continuum(ptr);

  case MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET:
  case MEMCACHED_DISTRIBUTION_MODULA:
    break;

  case MEMCACHED_DISTRIBUTION_RANDOM:
    srandom((uint32_t) time(NULL));
    break;

  case MEMCACHED_DISTRIBUTION_CONSISTENT_MAX:
  default:
    assert_msg(0, "Invalid distribution type passed to run_distribution()");
  }

  return MEMCACHED_SUCCESS;
}


四、memcached_generate_hash_with_redistribution

memcached_set中会调用memcached_generate_hash_with_redistribution来获得一个serverID。

1、首先调用_generate_hash_wrapper(),最终调用hashkit_one_at_a_time ()计算key的哈希值。

2、_regen_for_auto_eject(ptr),对于MEMCACHED_DISTRIBUTION_MODULA,什么也不做。
3、dispatch_host(ptr, hash)

static uint32_t dispatch_host(const memcached_st *ptr, uint32_t hash)
{
  switch (ptr->distribution)
  {
  case MEMCACHED_DISTRIBUTION_CONSISTENT:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_WEIGHTED:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
    {
      uint32_t num= ptr->ketama.continuum_points_counter;
      WATCHPOINT_ASSERT(ptr->ketama.continuum);

      memcached_continuum_item_st *begin, *end, *left, *right, *middle;
      begin= left= ptr->ketama.continuum;
      end= right= ptr->ketama.continuum + num;

      while (left < right)
      {
        middle= left + (right - left) / 2;
        if (middle->value < hash)
          left= middle + 1;
        else
          right= middle;
      }
      if (right == end)
        right= begin;
      return right->index;
    }
  case MEMCACHED_DISTRIBUTION_MODULA:
    return hash % memcached_server_count(ptr);  
  case MEMCACHED_DISTRIBUTION_RANDOM:
    return (uint32_t) random() % memcached_server_count(ptr);
  case MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET:
    {
      return memcached_virtual_bucket_get(ptr, hash);
    }
  default:
  case MEMCACHED_DISTRIBUTION_CONSISTENT_MAX:
    WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */
    return hash % memcached_server_count(ptr);
  }
  /* NOTREACHED */
}

可以看出:对于MEMCACHED_DISTRIBUTION_MODULA,只是简单的将hash % memcached_server_count(ptr),从而获得了一个serverID。


五、引子:Ketama一致性哈希算法(转载)

转载自http://langyu.iteye.com/blog/684087

一致性哈希算法(Consistent Hashing Algorithm)是一种分布式算法,常用于负载均衡。Memcached client也选择这种算法,解决将key-value均匀分配到众多Memcached server上的问题。它可以取代传统的取模操作,解决了取模操作无法应对增删Memcached Server的问题(增删server会导致同一个key,在get操作时分配不到数据真正存储的server,命中率会急剧下降),详细的介绍在这篇帖子中http://www.iteye.com/topic/611976(后文指代这篇文章的地方均称为引文)。 

[下面以Memcached的分布式问题为讨论点,但将Memcached server抽象为节点(Node)] 
引文中描述的一致性Hash算法有个潜在的问题是: 
     将节点hash后会不均匀地分布在环上,这样大量key在寻找节点时,会存在key命中各个节点的概率差别较大,无法实现有效的负载均衡。 
     如有三个节点Node1,Node2,Node3,分布在环上时三个节点挨的很近,落在环上的key寻找节点时,大量key顺时针总是分配给Node2,而其它两个节点被找到的概率都会很小。
 

这种问题的解决方案可以有: 
     改善Hash算法,均匀分配各节点到环上;[引文]使用虚拟节点的思想,为每个物理节点(服务器)在圆上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。用户数据映射在虚拟节点上,就表示用户数据真正存储位置是在该虚拟节点代表的实际物理服务器上。
 
     在查看Spy Memcached client时,发现它采用一种称为Ketama的Hash算法,以虚拟节点的思想,解决Memcached的分布式问题。
 

Ketama is an implementation of a consistent hashing algorithm, meaning you can add 
or remove servers from the memcached pool without causing a complete remap of all keys. 
Here’s how it works: 
* Take your list of servers (eg: 1.2.3.4:11211, 5.6.7.8:11211, 9.8.7.6:11211) 
* Hash each server string to several (100-200) unsigned ints 
* Conceptually, these numbers are placed on a circle called the continuum. 
(imagine a clock face that goes from 0 to 2^32) 
* Each number links to the server it was hashed from, so servers appear at several 
points on the continuum, by each of the numbers they hashed to. 
* To map a key->server, hash your key to a single unsigned int, and find the 
next biggest number on the continuum. The server linked to that number 
is the correct server for that key. 
* If you hash your key to a value near 2^32 and there are no points on the 
continuum greater than your hash, return the first server in the continuum. 
If you then add or remove a server from the list, only a small proportion 
of keys end up mapping to different servers.

Java8揭秘(三)Default 方法

第二章  Default 方法 为什么要有Default方法 一旦Java8发布,有件事情就显得非常重要,即能在不破坏现有实现架构的情况下往接口里增加方法。之所以引入Default方法到Java8...
  • wwwsssaaaddd
  • wwwsssaaaddd
  • 2014年04月21日 01:46
  • 26629

vagrant学习笔记 - 入门

官网http://www.vagrantup.com/ 官方下载地址:https://www.vagrantup.com/downloads.html 旧版本下载:https://releases....
  • 54powerman
  • 54powerman
  • 2016年02月14日 15:10
  • 2376

关联规则R语言实现

原文地址:http://blog.csdn.net/wolfbloodbj/article/details/8836441 关联分析的挖掘任务可分解为两个步骤:一是发现频繁项集,二是从频繁项...
  • jiabiao1602
  • jiabiao1602
  • 2015年05月04日 00:11
  • 1108

关联规则R语言实现

文章参考资料: xccd:肖凯大牛的博文 《Rdatamining》 《R IN A NUTSHELL》 注:如有疑惑的问题,参阅下文的预备知识! 关...
  • wolfbloodbj
  • wolfbloodbj
  • 2013年04月22日 20:30
  • 6607

Java学习笔记(1):访问修饰符protected和default的区别

访问修饰符,即对访问范围的控制。在Java中,有以下几种访问修饰符: 1.对类而言: (1)public:在所有的包中均可见 (2)default(默认):只在该类所在包中可见 注:类不能用priva...
  • jinmo277
  • jinmo277
  • 2015年08月28日 19:49
  • 1658

Java接口的default method与多重继承

多重继承可被用来为类添加已定义的标准的功能,这又被成为mixin。Java(JDK1.8)中接口的缺省方法实现(default method)提供了对此的支持。 以JavaFX示例中的ens...
  • hk201406
  • hk201406
  • 2014年07月21日 12:01
  • 656

看java核心时候遇到的,以后再来看

Java8 新特性之集合: removeIf(Predicate filter) 原创 2017年04月12日 22:21:08 标签:java /jdk /源码 /removeIf 3...
  • hagle_wang
  • hagle_wang
  • 2017年12月04日 10:35
  • 49

SpringBoot学习笔记(2) Spring Boot的一些配置

Spring Boot允许使用properties文件、yaml文件或者命令行参数作为外部配置 使用@Value注解,可以直接将属性值注入到你的beans中,并通过Spring的Environment...
  • a67474506
  • a67474506
  • 2016年07月24日 13:15
  • 17820

Java 8 官方教程翻译——默认方法(default method)

在接口(interface)一节中提到了一个示例,其中涉及了一些发布工业标准接口的“计算机控制汽车“生产商,其发布的接口中描述了哪些方法(method)可以用来操作这些汽车。假如这些生产商需要给他们的...
  • cwt8805
  • cwt8805
  • 2014年12月25日 15:13
  • 890

Java 8的default方法详解

Java 8的default方法详解作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszsJava 8新增了default方法,它可以在接口添加新功能特性,而且还...
  • chszs
  • chszs
  • 2015年01月11日 16:26
  • 5637
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从MEMCACHED_DISTRIBUTION_MODULA开始
举报原因:
原因补充:

(最多只允许输入30个字)