PHP分布式路由算法介绍与实现
在我们做负载均衡,分布式部署,数据分表时,需要用到一些分布式路由算法将请求路由到真实的节点上。最常用的有哈希取模,一致性哈希算法等。这里对他们的做一些介绍及提供PHP实现。
场景举例:分布式缓存服务器路由
1、哈希取模算法
对缓存key进行hash得到结果取余数 (hash() mod N
):对机器编号从0到N-1,按照自定义的hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。
优点:实现简单
缺点:新增节点、删除节点引起的hash值颠簸,所有节点缓存需要重新计算迁移
function hashmod($key,$mod)
{$code =crc32($key);return abs($code) % $mod;
}
测试代码:
for($i = 1;$i<100;$i++){$key = 'cachekey_'.$i;$node = hashmod($key,10);$arr[$node][] = $key;}foreach($arr as $key=>$val){echo '节点'.$key.'数据量:'.count($val).PHP_EOL;}
结果:
2、一致性哈希算法(Consistent Hashing)
由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,-1]间,如果我们把一个圆环用个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~-1的圆上。
用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。
Consistent Hashing原理示意图
新增一个节点的时候,只有在圆环上新增节点逆时针方向的第一个节点的数据会受到影响。删除一个节点的时候,只有在圆环上原来删除节点顺时针方向的第一个节点的数据会受到影响,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。
Consistent Hashing添加服务器示意图
虚拟节点(virtual nodes):之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。
虚拟节点对Consistent Hashing结果的影响
从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。
class ConsistentHashing
{// 圆环// hash -> 节点private $_ring = array();// 所有节点// 节点 -> hashpublic $nodes = array();// 每个节点的虚拟节点public $virtual = 64;/*** 构造* @param array $nodes 初始化的节点列表*/public function __construct($nodes = array()){if (!empty($nodes)) {foreach ($nodes as $value) {$this->addNode($value);}}}/*** 获取圆环内容* @return array $this->_ring*/public function getRing(){return $this->_ring;}/*** time33 函数* @param string $str* @return 32位正整数* @author 大神们*/public function time33($str){$hash = 0;$s = md5($str);$len = 32;for ($i = 0; $i < $len; $i++) {$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;}return $hash;}/*** 增加节点* @param string $node 节点名称* @return object $this*/public function addNode($node){if (in_array($node, array_keys($this->nodes))) {return;}for ($i = 1; $i <= $this->virtual; $i++) {$key = $this->time33($node . '-' . $i);$this->_ring[$key] = $node;$this->nodes[$node][] = $key;}ksort($this->_ring, SORT_NUMERIC);return $this;}/*** 删除节点* @param string $node 节点名称*/public function removeNode($node){//删除虚拟节点foreach ($this->nodes[$node] as $k => $v) {unset($this->_ring[$v]);}//删除节点unset($this->nodes[$node]);return $this;}/*** 获取字符串的HASH在圆环上面映射到的节点* @param string $key* @return string $node*/public function getNode($key){$node = current($this->_ring);$hash = $this->time33($key);foreach ($this->_ring as $key => $value) {if ($hash <= $key) {$node = $value;break;}}return $node;}
}
用以下代码测试:
$ch = new ConsistentHashing(['node1','node2','node3','node4','node5','node6','node7','node8','node9','node10']);
echo '创建节点:node1 - node10'.PHP_EOL;
for($i=1;$i<=10;$i++){echo 'cachekey'.$i.' 分布节点:'.$ch->getNode('cachekey'.$i).PHP_EOL;
}
echo '_____________'.PHP_EOL;$ch->addNode('node11');
echo '增加节点:node11'.PHP_EOL;
for($i=1;$i<=10;$i++){echo 'cachekey'.$i.' 分布节点:'.$ch->getNode('cachekey'.$i).PHP_EOL;
}
echo '_____________'.PHP_EOL;$ch->removeNode('node8');
echo '删除节点:node8'.PHP_EOL;
for($i=1;$i<=10;$i++){echo 'cachekey'.$i.' 分布节点:'.$ch->getNode('cachekey'.$i).PHP_EOL;
}
结果如下:
PHP分布式路由算法介绍与实现相关推荐
- 笔者带你剖析三种常见的分布式路由算法
Redis.Memcache也好,MySQL也罢.当达到单点可处理的容量上线时,Sharding是一种解决痛点最直接的解决方案.假设对存储系统实施了Sharding,那么我们究竟应该如何选取合适的路由 ...
- 分布式一致性算法介绍
目录 1.Zab协议 2.raft协议 3.gossip 分布式数据一致性简单点理解就是在多个节点中同一时间视图时数据值是一致的.大体上可以将这些算法分为强一致性与弱一致性. 强一致性 zab协议(z ...
- ospf cost 引起路由可以ping通但应用无法连接_路由算法(通网五)
在通信网络中,网络层主要负责将两个终端系统经过网络中的节点用数据锥路连接起来,组成通信通路,实现两个终端系统之间数据的透明传送.所谓透明传输是指发端发送到网络接口的任何信息都会按照其原始的形式传送到接 ...
- 路由算法-链路状态路由
路由算法 网络层的主要功能是将数据包从源机器路由到目标机器.在大多数网络中,数据包需要经过多跳才能到达目的地.路由算法和这些算法所用的数据结构是网络层设计的最主要内容. 可以这样想,路由器内部 ...
- 区块链共识机制与分布式一致性算法
摘要: 本篇文章是[区块链之技术进阶]的第七篇文章,在之前的文章中咱们多多少少提及了共识算法等相关知识,但是却没有具体地更加深入地了解,本文就为大家掰一掰区块链共识机制与分布式一致性算法,两者究竟有什 ...
- 分布式块存储QoS限速算法介绍与实践以及对上层应用的影响
分布式块存储QoS限速算法以及对上层应用的影响 QoS限速算法介绍 令牌桶 Token Bucket 漏桶 Leaky Bucket Leaky bucket as a meter Leaky buc ...
- 分布式入门:常用的分布式基础算法
摘要: 研究生期间分布式课程的小结吧.... 中间件在分布式系统中的地位和角色 为了使种类各异的计算机和网络都呈现为单个的系统,分布式系统常常通过一个"软件层"组织起来,该层在逻辑 ...
- TCP/IP之路由算法
转载自https://www.jianshu.com/p/e5cce2958790 网络层的重要功能就是路由和转发.而路由是根据路由器根据所维护的路由表进行路由选择.所以,如果创建和更新转发表就是一个 ...
- 路由算法与收敛路由原理
当两台主机在不同的局域网内,它们之间要进行通信,必然要经过路由器,而当一个数据包达到路由器时,路由器会获取这个数据包的目的IP地址,而通过查看路由器的路由表,路由器会判断将这个数据包送往何处 首先对于 ...
最新文章
- linux如何关闭防火墙
- sumk跟spring boot的比较
- 卧加加工斜孔怎么计算机械坐标,卧加B轴旋转后坐标怎么计算
- 北京招聘 | 美团视觉智能中心招聘视觉算法实习生
- linux获取ip地址的接口,在Linux上获取接口的IP地址
- k8s问题 CrashLoopBackOff
- php代码格式化工具 php-cs-fixer的使用
- php连接函数config,smarty内置函数config_load用法实例
- 散粉在哪个步骤用_底妆的正确步骤是什么?花三分钟带你破译底妆密码
- Oracle scheduler job管理
- IT公司是怎样面试的? (转载)
- widi软件|widi音频转换软件
- 谷歌放弃火狐的谷歌工具栏产品
- Swift-字符串和字符
- android 输入法更换_安卓手机怎么更换输入法-安卓手机切换输入法的方法 - 河东软件园...
- 06js超级玛丽小游戏
- 2021安徽阜阳高考成绩排名查询,2021年阜阳高考状元是谁分数多少分,历年阜阳高考状元名单...
- 链家网深圳租房信息分析报告
- 扇贝一面----Android面经
- 我的简约论坛php源码,我的论坛源代码(二)
热门文章
- ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.
- 让自己的底线一降再降,相当于没有底线
- AutoCAD如何方便截图放到Word文档,改成白底黑字
- 曝摩托罗拉下最后通牒:被裁员工最晚21日离职
- SEO中的简单代码优化
- Hazelcast IMDG学习 Map java demo
- 卖高价的洋水果是个好榜样
- 图像编辑系列之(2)基于StyleGAN(3)GAN逆映射(4)人脸 (5)语义生成 | ICCV2021生成对抗GAN梳理汇总...
- 我的世界JAVA会支持光追吗_光线追踪改变了「我的世界」,华硕ROG2060S显卡的光追体验...
- 【WebLogic】解决opatch执行报错“Exception occured: fuser could not be located”