一致性hash分步簡單理解:
將伺服器節點和key節點都按照Crc32函式部署。
簡單排序到圓環上。比如四臺伺服器,理想化可分佈在12 3 6 9點鐘四個位置。
然後根據key的crc32的值,找到離他最近的伺服器節點,放入。
希望各位前輩指教
<?php
// 將一個字串轉為整形的功能
interface hash{
public function _hash($str);
}
// 分發到某一臺伺服器
interface dispatch {
public function lookup($key);//查詢某個key
}
class Consitent implements hash,dispatch{
// 所有伺服器節點
protected $nodes=array();
public function _hash($str){
return sprintf(`%u`,crc32($str));//保持正數
}
//找到key在哪個伺服器節點上
public function lookup($key){
$point=$this->_hash($key);
$node=current($this->nodes);// 預設在第一個伺服器節點
//通過判斷所存key的hash值,與儲存的伺服器節點的key做對比,返回對應伺服器的value值
foreach ($this->nodes as $key => $value) {
if($point<=$key){
$node=$value;
break;
}
}
return $node;
}
// 新增伺服器節點
public function addNode($node){
$node_key=sprintf(`%u`,crc32($node));
$this->nodes[$node_key]=$node;// 按照鍵的節點排序
$this->sortNode();
}
public function printNodes(){
var_dump($this->nodes);// 列印所有伺服器節點列表
}
//將所有伺服器安裝順序大小排序,方便儲存和查詢
public function sortNode(){
ksort($this->nodes,SORT_REGULAR);
}
}
$c=new Consitent();
$c->addNode(`a`);
$c->addNode(`b`);
$c->addNode(`c`);
$c->printNodes();
echo $c->_hash(`name`);
echo $c->lookup(`name`);
缺點:無法均勻分部伺服器節點(只做到了按順序)
尤其是第一臺伺服器預設儲存的情況下。需要引入虛擬節點,將當前節點方法N倍,這樣再排序後,當前節點die掉後,可分攤減輕下一個節點遇到的壓力。
具體參考github牛人寫的php一致性hash類