<?php
/**
* 一致性哈希實現(xiàn)接口
* Interface ConsistentHash
*/
interface ConsistentHash
{
//將字符串轉(zhuǎn)為hash值
public function cHash(string $str): int;
//添加一臺服務(wù)器到服務(wù)器列表中
public function addServer(string $serverHost);
//從服務(wù)器刪除一臺服務(wù)器
public function removeServer(string $serverHost);
//在當前的服務(wù)器列表中找到合適的服務(wù)器存放數(shù)據(jù)
public function lookup(string $key);
}
/**
* 具體一致性哈希實現(xiàn)
* author chenqionghe
* Class MyConsistentHash
*/
class MyConsistentHash implements ConsistentHash
{
public $serverList = []; //服務(wù)器列列表
public $virtualPos = []; //虛擬節(jié)點的位置
public $virtualPosNum = 5; //每個節(jié)點對應(yīng)5個虛節(jié)點
/**
* 將字符串轉(zhuǎn)換成32位無符號整數(shù)hash值
* @param $str
* @return int
*/
public function cHash(string $str): int
{
$str = md5($str);
return sprintf('%u', crc32($str));
}
/**
* 添加一臺服務(wù)器到服務(wù)器列表中
* @param $server 服務(wù)器IP地址
* @return bool
*/
public function addServer(string $server)
{
if (!isset($this->serverList[$server])) {
//增加虛擬節(jié)點
for ($i = 0; $i < $this->virtualPosNum; $i++) {
$pos = $this->cHash($server . '#' . $i);
//存放虛擬節(jié)點存放的對應(yīng)的服務(wù)器
$this->virtualPos[$pos] = $server;
//存放單臺服務(wù)器包含的所有節(jié)點
$this->serverList[$server][] = $pos;
}
//虛擬節(jié)點根據(jù)位置排序
ksort($this->virtualPos, SORT_NUMERIC);
}
}
/**
* 移除一臺服務(wù)器(循環(huán)所有的虛節(jié)點,刪除值為該服務(wù)器地址的虛節(jié)點)
* @param $key
* @return bool
*/
public function removeServer($key)
{
if (isset($this->serverList[$key])) {
//刪除一臺服務(wù)器上的所有虛節(jié)點
foreach ($this->serverList[$key] as $pos) {
unset($this->virtualPos[$pos]);
}
//刪除對應(yīng)服務(wù)器
unset($this->serverList[$key]);
}
}
/**
* 在當前的服務(wù)器列表中找到合適的服務(wù)器存放數(shù)據(jù)
* @param $key 鍵名
* @return mixed 返回服務(wù)器IP地址
*/
public function lookup(string $key)
{
$point = $this->cHash($key);//落點的hash值
$finalServer = current($this->virtualPos);//先取圓環(huán)上最小的一個節(jié)點當成結(jié)果(數(shù)組的第一個索引單元)
//找到虛擬節(jié)點最接近的服務(wù)器
foreach ($this->virtualPos as $pos => $server) {
if ($point <= $pos) {
$finalServer = $server;
break;
}
}
reset($this->virtualPos);//重置圓環(huán)的指針為第一個(重置數(shù)組的指針)
return $finalServer;
}
}
$hashServer = new MyConsistentHash();
$hashServer->addServer('192.168.1.1');
$hashServer->addServer('192.168.1.2');
$hashServer->addServer('192.168.1.3');
$hashServer->addServer('192.168.1.4');
$hashServer->addServer('192.168.1.5');
$hashServer->addServer('192.168.1.6');
$hashServer->addServer('192.168.1.7');
$hashServer->addServer('192.168.1.8');
$hashServer->addServer('192.168.1.9');
$hashServer->addServer('192.168.1.10');
echo "增加十臺服務(wù)器192.168.1.1~192.168.1.10<br />";
echo "保存 key1 到 server :".$hashServer->lookup('key1') . '<br />';
echo "保存 key2 到 server :".$hashServer->lookup('key2') . '<br />';
echo "保存 key3 到 server :".$hashServer->lookup('key3') . '<br />';
echo "保存 key4 到 server :".$hashServer->lookup('key4') . '<br />';
echo "保存 key5 到 server :".$hashServer->lookup('key5') . '<br />';
echo "保存 key6 到 server :".$hashServer->lookup('key6') . '<br />';
echo "保存 key7 到 server :".$hashServer->lookup('key7') . '<br />';
echo "保存 key8 到 server :".$hashServer->lookup('key8') . '<br />';
echo "保存 key9 到 server :".$hashServer->lookup('key9') . '<br />';
echo "保存 key10 到 server :".$hashServer->lookup('key10') . '<br />';
echo "<pre>";
print_r($hashServer->virtualPos);
名稱欄目:PHP實現(xiàn)一致性hash
文章出自:http://www.rwnh.cn/article2/jehooc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、企業(yè)建站、App設(shè)計、網(wǎng)站設(shè)計公司、定制網(wǎng)站、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)