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连接mysql数据库代码
Mar 10 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
Nov 24 PHP
Linux fgetcsv取得的数组元素为空字符串的解决方法
Nov 25 PHP
PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
Apr 09 PHP
php开发微信支付获取用户地址
Oct 04 PHP
WordPress中获取指定分类及其子分类下的文章数目
Dec 31 PHP
YII2 实现多语言配置的方法分享
Jan 11 PHP
php session的应用详细介绍
Mar 22 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
May 23 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
Feb 13 PHP
PHP+jQuery实现即点即改功能示例
Feb 21 PHP
PHP ob缓存以及ob函数原理实例解析
Nov 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方法调用模式与函数调用模式简例
2011/09/20 PHP
PHP实现仿Google分页效果的分页函数
2015/07/29 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
PHP实现时间日期友好显示实现代码
2019/09/08 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
jQuery 使用手册(七)
2009/09/23 Javascript
js replace 与replaceall实例用法详解
2013/08/03 Javascript
javascript如何动态加载表格与动态添加表格行
2013/11/27 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
不同编码的页面表单数据乱码问题解决方法
2015/02/15 Javascript
Nodejs中 npm常用命令详解
2016/07/04 NodeJs
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
js给table赋值的实例代码
2016/10/13 Javascript
vue-router 路由基础的详解
2017/10/17 Javascript
vue 路由嵌套高亮问题的解决方法
2018/05/17 Javascript
页面点击小红心js实现代码
2018/05/26 Javascript
vue 权限认证token的实现方法
2018/07/17 Javascript
React+Webpack快速上手指南(小结)
2018/08/15 Javascript
简单了解JavaScript作用域
2020/07/31 Javascript
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
Python的requests网络编程包使用教程
2016/07/11 Python
Python脚本实现自动将数据库备份到 Dropbox
2017/02/06 Python
pandas中去除指定字符的实例
2018/05/18 Python
解决seaborn在pycharm中绘图不出图的问题
2018/05/24 Python
对Python3.6 IDLE常用快捷键介绍
2018/07/16 Python
Mac下Anaconda的安装和使用教程
2018/11/29 Python
Flask框架web开发之零基础入门
2018/12/10 Python
pytorch中的自定义反向传播,求导实例
2020/01/06 Python
美国高端寝具品牌:Coyuchi
2017/02/08 全球购物
日本即尚网:JSHOPPERS.com(支持中文)
2019/12/03 全球购物
爱祖国演讲稿
2014/05/04 职场文书
校本教研活动总结
2014/07/01 职场文书
普通党员对照检查材料
2014/08/28 职场文书
复兴之路观后感
2015/06/02 职场文书
金砖之国观后感
2015/06/11 职场文书
redis 查看所有的key方式
2021/05/07 Redis