标签:
一致性Hash分布算法分4个步骤:
步骤1:将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象。
步骤2:通过Hash函数把KEY处理成整数。这样就可以在环上找到一个位置与之对应。
步骤3:把Memcached服务器群映射到环上,使用Hash函数处理服务器对应的IP地址即可。
步骤4:把数据映射到Memcached服务器上。查找一个KEY对应的Memcached服务器位置的方法如下:从当前KEY的位置,沿着圆环顺时针方向出发,查找位置离得最近的一台Memcached服务器,并将KEY对应的数据保存在此服务器上。

代码实例:
<?php
/**
* 一致性Hash分布
* 天涯PHP博客
* http://blog.phpha.com
*/
class FlexiHash{
//服务器列表
private $serverList = array();
//记录是否已经排序
private $isSorted = FALSE;
//添加一台服务器
public function addServer($server){
$hash = $this->mHash($server);
if(!isset($this->serverList[$hash])){
$this->serverList[$hash] = $server;
}
//需要重新排序
$this->isSorted = FALSE;
return TRUE;
}
//移除一台服务器
public function removeServer($server){
$hash = $this->mHash($server);
if(isset($this->serverList[$hash])){
unset($this->serverList[$hash]);
}
//需要重新排序
$this->isSorted = FALSE;
return TRUE;
}
//在当前服务器列表查找合适的服务器
public function lookup($key){
$hash = $this->mHash($key);
//先进行倒序排序操作
if(!$this->isSorted){
krsort($this->serverList, SORT_NUMERIC);
$this->isSorted = TRUE;
}
//圆环上顺时针方向查找当前KEY紧邻的一台服务器
foreach($this->serverList as $pos => $server){
if($hash >= $pos) return $server;
}
//没有找到则返回顺时针方向最后一台服务器
return $this->serverList[count($this->serverList) - 1];
}
//Hash函数
private function mHash($key){
$md5 = substr(md5($key), 0, 8);
$seed = 31;
$hash = 0;
for($i = 0; $i < 8; $i++){
$hash = $hash * $seed + ord($md5{$i});
$i++;
}
return $hash & 0x7FFFFFFF;
}
}
?>
测试:
<?php
/**
* 一致性Hash分布测试代码
* 天涯PHP博客
* http://blog.phpha.com
*/
$hserver = new FlexiHash();
//初始5台服务器
$hserver->addServer("192.168.1.1");
$hserver->addServer("192.168.1.2");
$hserver->addServer("192.168.1.3");
$hserver->addServer("192.168.1.4");
$hserver->addServer("192.168.1.5");
echo "save key1 in server: ", $hserver->lookup(‘key1‘), "<br/>";
echo "save key2 in server: ", $hserver->lookup(‘key2‘), "<br/>";
echo ‘===============================================<br/>‘;
//移除1台服务器
$hserver->removeServer("192.168.1.4");
echo "save key1 in server: ", $hserver->lookup(‘key1‘), "<br/>";
echo "save key2 in server: ", $hserver->lookup(‘key2‘), "<br/>";
echo ‘===============================================<br/>‘;
//添加1台服务器
$hserver->addServer(‘192.168.1.6‘);
echo "save key1 in server: ", $hserver->lookup(‘key1‘), "<br/>";
echo "save key2 in server: ", $hserver->lookup(‘key2‘);
?>
//测试结果如下:
save key1 in server: 192.168.1.4
save key2 in server: 192.168.1.2
==================================
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.2
==================================
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.2
标签:
原文地址:http://www.cnblogs.com/icyy/p/5198998.html