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 相关文章推荐
常用的php ADODB使用方法集锦
Mar 25 PHP
php session_start()关于Cannot send session cache limiter - headers already sent错误解决方法
Nov 27 PHP
PHP字符串的连接的简单实例
Dec 30 PHP
PHP中ini_set和ini_get函数的用法小结
Feb 18 PHP
PHP遍历XML文档所有节点的方法
Mar 12 PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
May 11 PHP
一个完整的php文件上传类实例讲解
Oct 27 PHP
PHP导出Excel实例讲解
Jan 24 PHP
PHP共享内存用法实例分析
Feb 12 PHP
PHP文件及文件夹操作之创建、删除、移动、复制
Jul 13 PHP
解决laravel5中auth用户登录其他页面获取不到登录信息的问题
Oct 08 PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 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读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
php封装json通信接口详解及实例
2017/03/07 PHP
PHP Cli 模式设置进程名称的方法
2019/06/12 PHP
Javascript 入门基础学习
2010/03/10 Javascript
jquery模拟按下回车实现代码
2011/09/20 Javascript
js数组的操作详解
2013/03/27 Javascript
JavaScript和JQuery的鼠标mouse事件冒泡处理
2015/06/19 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
jQuery复制表单元素附源码分享效果演示
2015/09/30 Javascript
高性能JavaScript循环语句和条件语句
2016/01/20 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
2018/09/20 Javascript
详解用场景去理解函数柯里化(入门篇)
2019/04/11 Javascript
微信小程序的tab选项卡的实现效果
2019/05/15 Javascript
Vue中全局变量的定义和使用
2019/06/05 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
python发送伪造的arp请求
2014/01/09 Python
Python实现读取txt文件并画三维图简单代码示例
2017/12/09 Python
Python实现改变与矩形橡胶的线条的颜色代码示例
2018/01/05 Python
值得收藏,Python 开发中的高级技巧
2018/11/23 Python
我用Python抓取了7000 多本电子书案例详解
2019/03/25 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
pytorch进行上采样的种类实例
2020/02/18 Python
使用pandas实现筛选出指定列值所对应的行
2020/12/13 Python
简单html5代码获取地理位置
2014/03/31 HTML / CSS
韩国商务邀请函
2014/01/14 职场文书
管理失职检讨书
2014/02/12 职场文书
物流管理专业毕业生求职信
2014/03/23 职场文书
教师读书活动总结
2014/05/07 职场文书
解除劳动合同协议书(样本)
2014/10/02 职场文书
开场白怎么写
2015/06/01 职场文书
创业计划书之酒厂
2019/10/14 职场文书
SQL SERVER实现连接与合并查询
2022/02/24 SQL Server