一致性Hash算法(分布式算法)
一致性哈希算法是分布式系统中常用的算法,为什么要用这个算法?
一致性哈希算法的PHP实现
/**
* 一致性哈希实现接口
* Interface ConsistentHash
*/
interface ConsistentHash
{
//将字符串转为hash值
public function cHash($str);
//添加一台服务器到服务器列表中
public function addServer($server);
//从服务器删除一台服务器
public function removeServer($server);
//在当前的服务器列表中找到合适的服务器存放数据
public function lookup($key);
}
/**
* 具体一致性哈希实现
* author chenqionghe
* Class MyConsistentHash
*/
class MyConsistentHash implements ConsistentHash
{
public $serverList = array(); //服务器列列表
public $virtualPos = array(); //虚拟节点的位置
public $virtualPosNum = 5; //每个节点对应5个虚节点
/**
* 将字符串转换成32位无符号整数hash值
* @param $str
* @return int
*/
public function cHash($str)
{
$str = md5($str);
return sprintf('%u', crc32($str));
}
/**
* 在当前的服务器列表中找到合适的服务器存放数据
* @param $key 键名
* @return mixed 返回服务器IP地址
*/
public function lookup($key)
{
$point = $this->cHash($key);//落点的hash值
$finalServer = current($this->virtualPos);//先取圆环上最小的一个节点当成结果
foreach($this->virtualPos as $pos=>$server)
{
if($point <= $pos)
{
$finalServer = $server;
break;
}
}
reset($this->virtualPos);//重置圆环的指针为第一个
return $finalServer;
}
/**
* 添加一台服务器到服务器列表中
* @param $server 服务器IP地址
* @return bool
*/
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;
}
/**
* 移除一台服务器(循环所有的虚节点,删除值为该服务器地址的虚节点)
* @param $key
* @return bool
*/
public function removeServer($key)
{
if(isset($this->serverList[$key]))
{
//删除对应虚节点
foreach($this->serverList[$key] as $pos)
{
unset($this->virtualPos[$pos]);
}
//删除对应服务器
unset($this->serverList[$key]);
}
return TRUE;
}
}
$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 "增加十台服务器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 '<hr />';
echo "移除一台服务器192.168.1.2<br />";
$hashServer->removeServer('192.168.1.2');
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 '<hr />';
echo "移除一台服务器192.168.1.6<br />";
$hashServer->removeServer('192.168.1.6');
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 '<hr />';
echo "移除一台服务器192.168.1.8<br />";
$hashServer->removeServer('192.168.1.8');
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 '<hr />';
echo "移除一台服务器192.168.1.2<br />";
$hashServer->removeServer('192.168.1.2');
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 '<hr />';
echo "增加一台服务器192.168.1.11<br />";
$hashServer->addServer('192.168.1.11');
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 '<hr />';
运行结果如下
增加十台服务器192.168.1.1~192.168.1.10
保存 key1 到 server :192.168.1.2
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.6
保存 key4 到 server :192.168.1.8
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
移除一台服务器192.168.1.2
保存 key1 到 server :192.168.1.7
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.6
保存 key4 到 server :192.168.1.8
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
移除一台服务器192.168.1.6
保存 key1 到 server :192.168.1.7
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.3
保存 key4 到 server :192.168.1.8
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
移除一台服务器192.168.1.8
保存 key1 到 server :192.168.1.7
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.3
保存 key4 到 server :192.168.1.10
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
移除一台服务器192.168.1.2
保存 key1 到 server :192.168.1.7
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.3
保存 key4 到 server :192.168.1.10
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
增加一台服务器192.168.1.11
保存 key1 到 server :192.168.1.7
保存 key2 到 server :192.168.1.1
保存 key3 到 server :192.168.1.11
保存 key4 到 server :192.168.1.10
保存 key5 到 server :192.168.1.9
保存 key6 到 server :192.168.1.10
保存 key7 到 server :192.168.1.7
保存 key8 到 server :192.168.1.4
保存 key9 到 server :192.168.1.7
保存 key10 到 server :192.168.1.4
一致性Hash算法(分布式算法)的更多相关文章
- 分布式算法(一致性Hash算法)
一.分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法( ...
- 分布式缓存技术memcached学习(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几 ...
- 【转载】一致性hash算法释义
http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html 一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karge ...
- 一致性Hash算法及使用场景
一.问题产生背景 在使用分布式对数据进行存储时,经常会碰到需要新增节点来满足业务快速增长的需求.然而在新增节点时,如果处理不善会导致所有的数据重新分片,这对于某些系统来说可能是灾难性的. 那 ...
- 分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前, ...
- [转载] 一致性hash算法释义
转载自http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html 一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Ka ...
- php一致性hash算法的应用
阅读这篇博客前首先你需要知道什么是分布式存储以及分布式存储中的数据分片存储的方式有哪些? 分布式存储系统设计(2)—— 数据分片 阅读玩这篇文章后你会知道分布式存储的最优方案是使用 一致性hash算法 ...
- 分布式一致性hash算法
写在前面 在学习Redis的集群内容时,看到这么一句话:Redis并没有使用一致性hash算法,而是引入哈希槽的概念.而分布式缓存Memcached则是使用分布式一致性hash算法来实现分布式存储. ...
- 一致性Hash算法(Consistent Hash)
分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法(Re ...
随机推荐
- (29)Why Earth may someday look like Mars
https://www.ted.com/talks/anjali_tripathi_why_earth_may_someday_look_like_mars/transcript00:12So whe ...
- Springboot单例模式实战封装json转换
一.定义 保证一个类仅有一个实例,并提供一个全局访问点. 二.优点 (1)在内存里只有一个实例,减少了内存开销 (2)可以避免对资源的多重占用 (3)设置全局访问点,严格控制访问 ...
- Java类更改常量后编译不生效
在Java文件中,指向编译时static final的静态常量, 会被在运行时解析为一个局部的常量值(也就是说静态常量在编译后,成为了常量,而不是原先的代码).这对所有的基础数据类型(就像int ,f ...
- Numpy1
列表转n维数组ndarray import numpy as np list=[1,2,3,4] n=np.array(list) random模块生成ndarray n1=np.random.ran ...
- Python 递归 Resursion()
条件: ①递归有最小值或有确定值 ②fun(x) = ax * bfun(x-1) 类似规则 eg. n! : ①1! = 1 ②n! = n* (n-1)! def factorial (n): ...
- MySQL下创建数据库以及授权用户
一.新建数据库 1.首先登录MySQL:(输入 mysql -u root -p 命令,然后输入密码按回车即可) 2.在mysql> 下输入如下命令,回车,即可创建数据库 (test为数据库名) ...
- EBS五种安全性屏蔽解析
http://blog.11equals3.top/2018/02/09/190/ 分类帐集 定义: 分类帐集顾名思义就是分类账的集合.它是总帐提供的将相同科目表和相同日历的多个分类帐集合一起用于多分 ...
- css伪元素 ::after ::before
我遇到的问题: div盒子标签设置了伪元素 ::after ::before 并给这俩content内容设置了空属性,添加了背景图,发现这两个伪元素没有宽度和高度. 解决方法 给设置伪元素的盒子的 ...
- 【阿里聚安全·安全周刊】Intel芯片级安全漏洞事件|macOS存在漏洞
关键词:Intel漏洞丨mac OS漏洞丨三星漏洞丨安卓安全丨CPU漏洞丨phpMyAdmin漏洞丨iOS设备|安卓恶意软件检测|Burpsuite 本周资讯top3 [Intel漏洞]芯片级安全 ...
- Spring Boot 2 - 初识与新工程的创建
Spring Boot的由来 相信大家都听说过Spring框架. Spring从诞生到现在一直是流行的J2EE开发框架. 随着Spring的发展,它的功能越来越强大,随之而来的缺点也越来越明显,以至于 ...