援用大佬文章: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');
// 展现服务器的地位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