PHP一致性hash分布式算法封装类定义与用法示例


Posted in PHP onAugust 04, 2018

本文实例讲述了PHP一致性hash分布式算法封装类定义与用法。分享给大家供大家参考,具体如下:

一、无虚拟节点实现

<?php
/**
 * 一致性hash分布式算法
 * @param $key
 * @return int
 * 实现步骤
 * 1.先将0~ 是32位最大带符号整数(0x7FFFFFFF) 想象成一个闭环
 * 2.将服务器列表通过hash算法分布在 圆环之中
 * 3.将key值也分布在圆环之中
 * 4.通过_isSorted判断服务器是否需要进行倒序排序 排序后遍历服务器 找到最近的服务器 返回
 * hash算法是不保证平衡的 为了尽量保证平衡性 我们应该加入虚拟节点数 将一个服务器节点虚拟化成为多个 较大程度上保证了平衡性
 */
class FlexiHash{
  private $_serverList = array();
  private $_isSorted = false;
  private $_virtual_node_num = 20;//虚拟节点数 服务器越少 增加的虚拟节点数应该越多
  //通过hash算法返回一个整数值
  protected function myHash($key){
    $md5 = substr(md5($key),0,8);
    $seed = 31; //种子值
    $hash=0;
    for($i=0;$i<8;$i++){
      $hash = $hash*$seed+ord($md5{$i}); //ord 返回ascii值
      $i++;
    }
    return $hash&0x7FFFFFFF; //0x7FFFFFFF表示最大值
  }
  //添加服务器
  function addServer($server){
    $hash =$this->myHash($server. '#1');
    if(!isset($this->_serverList[$hash])) {
      for ($i = 1; $i <= $this->_virtual_node_num; $i++) {
        $hash = $this->myHash($server . '#' . $i);
        $this->_serverList[$hash] = $server;
      }
    }
    $this->_isSorted = false;
    return true;
  }
  //删除服务器
  function removeServer($server){
    for ($i = 1; $i <= $this->_virtual_node_num; $i++) {
      $hash = $this->myHash($server . '#' . $i);
      unset($this->_serverList[$hash]);
    }
    $this->_isSorted = false;
    return true;
  }
  //获取服务器
  function lookup($key){
    $hash =$this->myHash($key);
    if(!$this->_isSorted){
      krsort($this->_serverList,SORT_NUMERIC);
      $this->_isSorted = true;
    }
    foreach($this->_serverList as $pos=>$server){
      if($hash >= $pos) return $server;
    }
    return end($this->_serverList);
  }
  public function getServerList(){
    krsort($this->_serverList,SORT_NUMERIC);
    return $this->_serverList;
  }
}
//demo test
$hserver = new FlexiHash();
//添加服务器
$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');
$key1='Key1111';
$key2='Key2222';
$key2='Key3333';
$key2='Key4444';
$key2='Key5555';
$key2='Key6666';
echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;
echo "================================================".PHP_EOL;
//移除服务器 key值将自动转义到下一台服务器
$hserver->removeServer('192.168.1.4');
echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;
echo "================================================".PHP_EOL;
//恢复故障服务器 key值将恢复原来服务器
$hserver->addServer('192.168.1.4');
echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;
echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;
echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;

二、运行结果:

save key1 in server: 192.168.1.4
save key2 in server: 192.168.1.4
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3
================================================
save key1 in server: 192.168.1.2
save key2 in server: 192.168.1.5
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3
================================================
save key1 in server: 192.168.1.4
save key2 in server: 192.168.1.4
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3
save key1 in server: 192.168.1.3
save key2 in server: 192.168.1.3

PHP 相关文章推荐
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
Mar 15 PHP
在PHP中使用curl_init函数的说明
Nov 02 PHP
Zend的AutoLoad机制介绍
Sep 27 PHP
php连接mssql的一些相关经验及注意事项
Feb 05 PHP
php生成图片缩略图的方法
Apr 07 PHP
php实现修改新闻时删除图片的方法
May 12 PHP
Smarty简单生成表单元素的方法示例
May 23 PHP
thinkphp5 URL和路由的功能详解与实例
Dec 26 PHP
Laravel程序架构设计思路之使用动作类
Jun 07 PHP
PHP校验15位和18位身份证号的类封装
Nov 07 PHP
Laravel 集成微信用户登录和绑定的实现
Dec 27 PHP
PHPExcel实现的读取多工作表操作示例
Apr 14 PHP
PHP实现的函数重载功能示例
Aug 03 #PHP
thinkPHP5框架导出Excel文件简单操作示例
Aug 03 #PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 #PHP
PHP后台实现微信小程序登录
Aug 03 #PHP
thinkPHP5框架闭包函数与子查询传参用法示例
Aug 02 #PHP
PHP实现的AES加密、解密封装类与用法示例
Aug 02 #PHP
lnmp安装多版本PHP共存的方法详解
Aug 02 #PHP
You might like
php preg_filter执行一个正则表达式搜索和替换
2012/02/27 PHP
深入理解PHP内核(二)之SAPI探究
2015/11/10 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
javascript Demo模态窗口
2009/12/06 Javascript
通过上下左右键和回车键切换光标实现代码
2013/03/08 Javascript
JQUERY 实现窗口滚动搜索框停靠效果(类似滚动停靠)
2013/03/27 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
location.href用法总结(最主要的)
2013/12/27 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
javascript产生随机数方法汇总
2016/01/25 Javascript
jQuery 如何给Carousel插件添加新的功能
2016/04/18 Javascript
Bootstrap的Refresh Icon也spin起来
2016/07/13 Javascript
使用bootstrap插件实现模态框效果
2017/05/10 Javascript
node.js 发布订阅模式的实例
2017/09/10 Javascript
mint-ui的search组件在键盘显示搜索按钮的实现方法
2017/10/27 Javascript
简单明了区分escape、encodeURI和encodeURIComponent
2018/05/26 Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
2018/09/12 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
Python编程中的反模式实例分析
2014/12/08 Python
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
django js实现部分页面刷新的示例代码
2018/05/28 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
对Python 获取类的成员变量及临时变量的方法详解
2019/01/22 Python
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
使用Python的datetime库处理时间(RPA流程)
2019/11/24 Python
3种python调用其他脚本的方法
2020/01/06 Python
Pytorch实现神经网络的分类方式
2020/01/08 Python
浅谈Python线程的同步互斥与死锁
2020/03/22 Python
SheIn俄罗斯:时尚女装网上商店
2017/02/28 全球购物
酒后驾驶检讨书
2014/01/27 职场文书
七匹狼男装广告词
2014/03/21 职场文书
交警个人先进事迹材料
2014/05/11 职场文书
大学生创业计划书怎么写
2014/09/15 职场文书
vue实现简单数据双向绑定
2021/04/28 Vue.js
解析MySQL binlog
2021/06/11 MySQL