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之后的映射