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 相关文章推荐
PHP4实际应用经验篇(1)
Oct 09 PHP
《PHP边学边教》(01.开篇――准备工作)
Dec 13 PHP
PHP获得用户使用的代理服务器ip即真实ip
Dec 31 PHP
php实现ip白名单黑名单功能
Mar 12 PHP
PHP flush 函数使用注意事项
Aug 26 PHP
php表单加入Token防止重复提交的方法分析
Oct 10 PHP
php计算多个集合的笛卡尔积实例详解
Feb 16 PHP
浅谈thinkphp5 instance 的简单实现
Jul 30 PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
Apr 20 PHP
php实现数组中出现次数超过一半的数字的统计方法
Oct 14 PHP
ThinkPHP5.0框架使用build 自动生成模块操作示例
Apr 11 PHP
YII2框架中behavior行为的理解与使用方法示例
Mar 13 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 可变函数使用小结
2018/06/12 PHP
javascript引用对象的方法
2007/01/11 Javascript
常用的JavaScript验证正则表达式汇总
2013/11/26 Javascript
jquery 操作iframe的几种方法总结
2013/12/13 Javascript
通过$(this)使用jQuery包装后的方法或属性
2014/05/18 Javascript
一个支持任意尺寸的图片上下左右滑动效果
2014/08/24 Javascript
js实现类似MSN提示的页面效果代码分享
2015/08/24 Javascript
详解jquery validate实现表单验证 (正则表达式)
2017/01/18 Javascript
layui实现动态和静态分页
2018/04/28 Javascript
jquery拖拽自动排序插件使用方法详解
2020/07/20 jQuery
Vue.js上传图片到阿里云OSS存储的方法示例
2018/12/13 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
解决VUE双向绑定失效的问题
2019/10/29 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
在Echarts图中给坐标轴加一个标识线markLine
2020/07/20 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
2020/11/07 Javascript
python中Flask框架简单入门实例
2015/03/21 Python
python定时执行指定函数的方法
2015/05/27 Python
Python创建模块及模块导入的方法
2015/05/27 Python
使用Python对SQLite数据库操作
2017/04/06 Python
单利模式及python实现方式详解
2018/03/20 Python
启动Atom并运行python文件的步骤
2018/11/09 Python
python如何实现视频转代码视频
2019/06/17 Python
python爬虫 爬取58同城上所有城市的租房信息详解
2019/07/30 Python
Python列表list常用内建函数实例小结
2019/10/22 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
2019/11/15 Python
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
网页切图的CSS和布局经验与要点
2015/04/09 HTML / CSS
如何用PHP实现邮件发送
2012/12/26 面试题
英语硕士生求职简历的自我评价
2013/10/15 职场文书
酒店管理毕业生自荐信
2013/10/24 职场文书
考试没考好检讨书
2014/01/31 职场文书
总经理岗位职责范本
2014/02/02 职场文书
班主任工作经验材料
2014/02/02 职场文书
工程专业应届生求职信
2014/02/19 职场文书
Python实现查询剪贴板自动匹配信息的思路详解
2021/07/09 Python