简版一致性hash算法实现

 1     public function hashAction(){
 2             $server_list = range(14,114);
 3             $server_slot = $this->hashAri($server_list);
 4             $key_list = range(1,100000);
 5             $key_slot = $this->hashAri($key_list);
 6           
 7             //分配位子
 8             $result = $this->hashSlot($server_slot,$key_slot);
 9             $count = count($key_list);
10             foreach ($result as $key=>$val){
11                 echo "slot = ".$key." rate=".count($val)/$count."<br>";
12             }
13         }
14         
15         public function hashSlot($server_slot,$key_slot){
16             $result = array();
17             $min = 0;
18             foreach ($server_slot as $key=>$value){
19                 $max = $key;
20                 foreach ($key_slot as $k=>$v){
21                     if($k>$min && $k<$max)$result[$value][] = $v;
22                 }
23                 $min = $key;
24             }
25             return $result;
26         }
27         
28         public function hashAri($list){
29             $result = array();
30             foreach ($list as $key){
31                 $slot = rand(1,pow(2,30));
32                 $result[$slot] = $key;
33             }
34             ksort($result);
35             return $result;
36         }

 
 
 
解决问题:

  一般取余数的hash算法,新增或者删除机器,几乎所有的key都需要重新映射

原理:

将机器和key都按照同一个hash算法,映射到一个圆环上,所有的key顺时针,寻找离他最近的机器,找到并存储到该机器上

为了解决分布不均问题:

虚拟机器id

    就是把实体机器,复制出几个虚拟id,映射到圆环上,一定程度可以负载均衡

图例:

正常的一致性hash映射

删掉一个机器的映射

添加虚拟id之后的映射

    
原文地址:https://www.cnblogs.com/maggie94/p/6383679.html