一致性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 ...
随机推荐
- mysql ERROR 1451 (23000)
问题描述:报错如下:ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint提示有外键约束, ...
- spring BeanWrapperImpl方便的嵌套属性(list)操作
beans 包主要提供了接口和类用于处理java beans. 其中最主要的接口是BeanWrapper: Spring 的中心接口,用于访问javabeans 的低层操作.默认实现为 ...
- 20个Linux防火墙应用技巧
转载 1.显示防火墙的状态 以root权限运行下面的命令: # iptables -L -n -v 参数说明: -L:列出规则. -v:显示详细信息.此选项会显示接口名称.规则选项和TOS掩码,以及封 ...
- _ZNote_Qt_添加图标方法
简单来说就两步: 将icns图标添加入资源文件,例如picture.icns .pro文件中添加 (图标) ICON = picture.icns 程序中添加(程序窗口上显示) setWindowIc ...
- 制作系统U盘
没有任何宣传软件成分昂,我就是这做的. 1.在百度搜索上搜索“通用PE大师”,点开了这个网站http://up.6615261.cn/index.html,打开之后如下图,下载这个二合一版本 2.在电 ...
- 我所理解的HTTP协议
前言 对于HTTP协议,想必大家都不陌生,在工作中经常用到,特别是针对移动端和前端开发人员来说,要获取服务端数据,基本走的网络请求都是基于HTTP协议,特别是RESTFUL + JSON 这种搭配特别 ...
- python爬虫学习之日志记录模块
这次的代码就是一个日志记录模块,代码很容易懂,注释很详细,也不需要安装什么库.提供的功能是日志可以显示在屏幕上并且保存在日志文件中.调用的方式也很简单,测试代码里面有. 源代码: #encoding= ...
- Vue过渡mode属性踩坑
近期学习Vue的过渡效果的时候,mode属性的"in-out"."out-in"设置了不起作用,官网上的例子让我看了有点迷,问题解决后以此文记录之. 首先我们看 ...
- 10. 面向holder编程、自动轮询
没有看过上一篇文章的话,建议先去阅读GooglePlay:9.代码抽取(adapter) 项目框架的搭建: 以后每个view都是holder BaseHolder public abstract cl ...
- 《http权威指南》读书笔记13
概述 最近对http很感兴趣,于是开始看<http权威指南>.别人都说这本书有点老了,而且内容太多.我个人觉得这本书写的太好了,非常长知识,让你知道关于http的很多概念,不仅告诉你怎么做 ...