援用大佬文章: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