Memcached 之PHP實現服務器集羣一致性hash算法

/**
 * memcached 一致性hash,分佈式算法
 * Class MemcacheCluster
 */
class MemcacheCluster
{
    protected $nodes = array(); //服務器節點
    protected $position = array(); //虛擬節點
    protected $virtualNum = 32;  //每一個節點有32個虛擬節點;具體數量也能夠 16 ,8等

    public function hash($str)
    {
        //將字符串轉成32位符號整數
        return sprintf("%u", crc32($str));
    }

    //查找key 落到哪一個節點上
    public function findNode($key)
    {
        $point = $this->hash($key);

        //先取圓環上最小的一個節點
        //$key 哈希後比最大的節點都大就放到第一個節點
        $node = current($this->position);
        //下面這個查找能夠後期優化爲二分查找法。
        foreach ($this->position as $k => $v) {
            if ($point <= $k) {
                $node = $v;
                break;
            }
        }
        //復位數組指針
        reset($this->position);
        return $node;
    }

    public function addNode($node)
    {
        if (isset($this->nodes[$node])) {
            return;
        }
        for ($i = 0; $i < $this->virtualNum; $i++) {
            $pos = $this->hash($node . '-' . $i);
            $this->position[$pos] = $node;
            //方便刪除對應的虛擬節點
            $this->nodes[$node][] = $pos;
        }
        $this->sortPos();
    }

    public function delNode($node)
    {
        if (!isset($this->nodes[$node])) {
            return;
        }
        //循環全部的虛節點,誰的值==指定的真實節點 ,就把他刪掉
        foreach ($this->nodes[$node] as $k) {
            unset($this->position[$k]);
        }
        unset($this->nodes[$node]);
    }

    protected function sortPos()
    {
        //將虛擬節點排序
        //把每一項按常規順序排列(Standard ASCII,不改變類型)
        ksort($this->position, SORT_REGULAR);
    }
}
相關文章
相關標籤/搜索