php memcache 一致性hash入門

牙小木木發表於2016-03-08

一致性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類

相關文章