Memcached 一致性哈希算法PHP實(shí)現(xiàn)

<?php

// 一致性哈希算法
class ConsistentHashing
{
    protected $nodes = [];
    protected $position = [];
    protected $mul = 64;  // 每個(gè)節(jié)點(diǎn)對(duì)應(yīng)64個(gè)虛擬節(jié)點(diǎn)

    /**
     * 把字符串轉(zhuǎn)為32位符號(hào)整數(shù)
     */
    public function hash($str)
    {
        return sprintf('%u', crc32($str));
    }

    /**
     * 核心功能
     */
    public function lookup($key)
    {
        $point = $this->hash($key);

        //先取圓環(huán)上最小的一個(gè)節(jié)點(diǎn),當(dāng)成結(jié)果
        $node = current($this->position);

        // 循環(huán)獲取相近的節(jié)點(diǎn)
        foreach ($this->position as $key => $val) {
            if ($point <= $key) {
                $node = $val;
                break;
            }
        }

        reset($this->position);

        return $node;
    }

    /**
     * 添加節(jié)點(diǎn)
     */
    public function addNode($node)
    {
        if(isset($this->nodes[$node])) return;

        // 添加節(jié)點(diǎn)和虛擬節(jié)點(diǎn)
        for ($i = 0; $i < $this->mul; $i++) {
            $pos = $this->hash($node . '-' . $i);
            $this->position[$pos] = $node;
            $this->nodes[$node][] = $pos;
        }

        // 重新排序
        $this->sortPos();
    }

    /**
     * 刪除節(jié)點(diǎn)
     */
    public function delNode($node)
    {
        if (!isset($this->nodes[$node])) return;

        // 循環(huán)刪除虛擬節(jié)點(diǎn)
        foreach ($this->nodes[$node] as $val) {
            unset($this->position[$val]);
        }

        // 刪除節(jié)點(diǎn)
        unset($this->nodes[$node]);
    }

    /**
     * 排序
     */
    public function sortPos()
    {
        ksort($this->position, SORT_REGULAR);
    }
}


// 測(cè)試
$con = new ConsistentHashing();

$con->addNode('a');
$con->addNode('b');
$con->addNode('c');
$con->addNode('d');

$key1 = 'www.zhihu.com';
$key2 = 'www.baidu.com';
$key3 = 'www.google.com';

echo 'key' . $key1 . '落在' . $con->lookup($key1) . '號(hào)節(jié)點(diǎn)上!<br>';
echo 'key' . $key2 . '落在' . $con->lookup($key2) . '號(hào)節(jié)點(diǎn)上!<br>';
echo 'key' . $key3 . '落在' . $con->lookup($key3) . '號(hào)節(jié)點(diǎn)上!<br>';

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容