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 相关文章推荐
防止MySQL注入或HTML表单滥用的PHP程序
Jan 21 PHP
如何用phpmyadmin设置mysql数据库用户的权限
Jan 09 PHP
处理(php-cgi.exe - FastCGI 进程超过了配置的请求超时时限)的问题
Jul 03 PHP
PHP加密解密字符串汇总
Apr 26 PHP
PHP+ajax分页实例简析
Dec 07 PHP
php计划任务之验证是否有多个进程调用同一个job的方法
Dec 07 PHP
PHP 信号管理知识整理汇总
Feb 19 PHP
php实现基于PDO的预处理示例
Mar 28 PHP
PHP实现根据数组的值进行分组的方法
Apr 20 PHP
php获取微信共享收货地址的方法
Dec 21 PHP
Yii2框架实现登陆添加验证码功能示例
Jul 12 PHP
PHP PDOStatement::execute讲解
Jan 31 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 大数据量及海量数据处理算法总结
2011/05/07 PHP
PHP高自定义性安全验证码代码
2011/11/27 PHP
PHP实现的QQ空间g_tk加密算法
2015/07/09 PHP
PHP文件操作实例总结
2016/09/27 PHP
php微信公众号开发之音乐信息
2018/10/20 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
JavaScript 在各个浏览器中执行的耐性
2009/04/06 Javascript
javascript实现的使用方向键控制光标在table单元格中切换
2010/11/17 Javascript
解析JavaScript中delete操作符不能删除的对象
2013/12/03 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
javascript的正则匹配方法学习
2016/02/24 Javascript
js实现div在页面拖动效果
2016/05/04 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
Javascript之Date对象详解
2016/06/07 Javascript
全面了解函数声明与函数表达式、变量提升
2016/08/09 Javascript
JS实现touch 点击滑动轮播实例代码
2017/01/19 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
2017/03/02 Javascript
作为老司机使用 React 总结的 11 个经验教训
2017/04/08 Javascript
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
基于JSON数据格式详解
2017/08/31 Javascript
vue2过滤器模糊查询方法
2018/09/16 Javascript
layui实现下拉复选功能的例子(包括数据的回显与上传)
2019/09/24 Javascript
python3.6下Numpy库下载与安装图文教程
2019/04/02 Python
python-web根据元素属性进行定位的方法
2019/12/13 Python
python主线程与子线程的结束顺序实例解析
2019/12/17 Python
Python进程的通信Queue、Pipe实例分析
2020/03/30 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
CSS3打造磨砂玻璃背景效果
2016/09/28 HTML / CSS
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
机械设计及其自动化专业推荐信
2013/10/31 职场文书
大学生期末自我鉴定
2014/02/01 职场文书
2014道德模范事迹材料
2014/02/16 职场文书
跑操口号
2014/06/12 职场文书
应聘教师求职信
2014/07/19 职场文书
Spring事务管理下synchronized锁失效问题的解决方法
2022/03/31 Java/Android