引用大佬文章: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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。