引用大佬文章: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
【PHP实现Hash环/Hash一致性原理】
文章图片