引用大佬文章:Hash环

class consisTenHash{
    public $serverList = [];    // 服务器列表

    public $virtualPos = [];    // 虚拟节点位置

    public $virtualPosNum = 2;    // 每个节点下有2个虚节点

    /**
     使用循环冗余算法计算出十进制校验值
    **/ 
    public function cHash($str){
        $str = md5($str);
        return sprintf('%u',crc32($str));
    }

    /**
     从当前的服务器列表中找到合适的服务器进行存放
    **/
    public function lookup($key){
        $point = $this->cHash($key);
        $finalServer = current($this->virtualPos);
        foreach ($this->virtualPos as $pos => $server) {
            if($point <= $pos){
                $finalServer = $server;
                break;
            }
        }
        reset($this->virtualPos);
        return $finalServer;
    }

    /**
     添加一台服务器节点
    **/
    public function addServer($server){
        if (!isset($this->serverList[$server])) {
            for ($i=0; $i < $this->virtualPosNum; $i++) { 
                $pos = $this->cHash($server.'_'.$i);
                $this->virtualPos[$pos]         = $server;
                $this->serverList[$server][]     = $pos;
            }
            ksort($this->virtualPos,SORT_NUMERIC);
        }
        return true;
    }

    /**
     删除一台服务器节点
    **/
    public function delServer($key){
        if(isset($this->serverList[$key])){
            // 删除节点
            foreach ($this->serverList[$key] as $pos) {
                unset($this->virtualPos[$pos]);
            }
            //删除对应服务器
            unset($this->serverList[$key]);
        }
        return true;
    }
}

测试代码:

// 添加五台服务器
$consisTenHash  = new consisTenHash();
$consisTenHash->addServer('127.0.0.1');
$consisTenHash->addServer('127.0.0.2');
$consisTenHash->addServer('127.0.0.3');
$consisTenHash->addServer('127.0.0.4');
$consisTenHash->addServer('127.0.0.5');

image.png

// 展示服务器的位置
var_dump($consisTenHash->serverList);

// 添加Key,找到其存放的服务器位置
var_dump($consisTenHash->lookup("zxxxxx"));
var_dump($consisTenHash->lookup("rrrrrrrrr-c-1i312"));
var_dump($consisTenHash->lookup("shhjjaaaaaaa"));
var_dump($consisTenHash->lookup("blue-ssallllllkk"));
var_dump($consisTenHash->lookup("unset-bjhujka"));
var_dump($consisTenHash->lo

image.png


少年吖少年
65 声望2 粉丝