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防注
Jan 15 PHP
dedecms 制作模板中使用的全局标记图文教程
Mar 11 PHP
探讨PHP中OO之静态关键字以及类常量的详解
Jun 07 PHP
本地机apache配置基于域名的虚拟主机详解
Aug 10 PHP
php计算当前程序执行时间示例
Apr 24 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
May 12 PHP
CodeIgniter启用缓存和清除缓存的方法
Jun 12 PHP
将PHP从5.3.28升级到5.3.29时Nginx出现502错误
May 09 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
May 28 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
Aug 10 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
Apr 10 PHP
php实现的数组转xml案例分析
Sep 28 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 Smarty生成EXCEL文档的代码
2008/08/23 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
2011/12/05 PHP
php数组声明、遍历、数组全局变量使用小结
2013/06/05 PHP
PHP向socket服务器收发数据的方法
2015/01/24 PHP
php关键字仅替换一次的实现函数
2015/10/29 PHP
QQ邮箱的一个文本编辑器代码
2007/03/14 Javascript
javascript同步Import,同步调用外部js的方法
2008/07/08 Javascript
JS实现的仿QQ空间图片弹出效果代码
2016/02/23 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
Vue.js bootstrap前端实现分页和排序
2017/03/10 Javascript
解决VUE双向绑定失效的问题
2019/10/29 Javascript
es6函数之尾调用优化实例分析
2020/04/25 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
python 获取指定文件夹下所有文件名称并写入列表的实例
2018/04/23 Python
python调用百度REST API实现语音识别
2018/08/30 Python
python遍历小写英文字母的方法
2019/01/02 Python
python实现矩阵打印
2019/03/02 Python
Python3 执行Linux Bash命令的方法
2019/07/12 Python
通过Python编写一个简单登录功能过程解析
2019/09/04 Python
python中执行smtplib失败的处理方法
2020/07/01 Python
localStorage、sessionStorage使用总结
2017/11/17 HTML / CSS
canvas 阴影和图形变换的示例代码
2018/01/02 HTML / CSS
FC-Moto西班牙:摩托车手最大的购物场所之一
2019/04/11 全球购物
法国女性内衣购物网站:Glamuse
2019/05/13 全球购物
Linux操作面试题
2012/05/16 面试题
简洁的英文求职信范文
2014/05/03 职场文书
住房抵押登记委托书
2014/09/27 职场文书
面试通知邮件
2015/04/20 职场文书
2015年党风建设工作总结
2015/04/29 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
神秘岛读书笔记
2015/07/01 职场文书
2015党建工作简报
2015/07/21 职场文书
2016小学教师读书心得体会
2016/01/13 职场文书
MySQL中order by的执行过程
2022/06/05 MySQL
移除Selenium中window.navigator.webdriver值
2022/06/10 Python