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 相关文章推荐
判“新”函数:得到今天与明天的秒数
Oct 09 PHP
关于PHP5 Session生命周期介绍
Mar 02 PHP
php 编写安全的代码时容易犯的错误小结
May 20 PHP
php smarty 二级分类代码和模版循环例子
Jun 01 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
Oct 27 PHP
基于php使用memcache存储session的详解
Jun 25 PHP
php中autoload的用法总结
Nov 08 PHP
PHP实现加强版加密解密类实例
Jul 29 PHP
PHP使用SOAP扩展实现WebService的方法
Apr 01 PHP
PHP生成图片缩略图类示例
Jan 12 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
Feb 17 PHP
彻底搞懂PHP 变量结构体
Oct 11 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
Thinkphp搜索时首页分页和搜索页保持条件分页的方法
2014/12/05 PHP
php封装实现钉钉机器人报警接口的示例代码
2020/08/08 PHP
Nigma vs Liquid BO3 第一场2.14
2021/03/10 DOTA
js类中获取外部函数名的方法
2007/08/19 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
2013/01/15 Javascript
JavaScript 验证码的实例代码(附效果图)
2013/03/22 Javascript
Javascript表格翻页效果的具体实现
2013/10/05 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
Js获取下拉框选定项的值和文本的实现代码
2014/02/26 Javascript
jQuery学习笔记之jQuery.fn.init()的参数分析
2014/06/09 Javascript
jQuery+jRange实现滑动选取数值范围特效
2015/03/14 Javascript
jQuery实现的放大镜效果示例
2016/09/13 Javascript
JavaScript 闭包详细介绍
2016/09/28 Javascript
javascript 数组去重复(在线去重工具)
2016/12/17 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
Vue如何引入远程JS文件
2017/04/20 Javascript
vue.js实现刷新当前页面的方法教程
2017/07/05 Javascript
webpack3之loader全解析
2017/10/26 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
今天,小程序正式支持 SVG
2019/04/20 Javascript
vue使用i18n实现国际化的方法详解
2019/09/05 Javascript
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
Python学习小技巧之列表项的拼接
2017/05/20 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
django使用django-apscheduler 实现定时任务的例子
2019/07/20 Python
pyqt5 textEdit、lineEdit操作的示例代码
2020/08/12 Python
VSCODE配置Markdown及Markdown基础语法详解
2021/01/19 Python
SNIDEL官网:日本VIVI杂志人气少女第一品牌
2020/03/12 全球购物
党课培训主持词
2014/04/01 职场文书
信息工作经验交流材料
2014/05/28 职场文书
小学少先队辅导员述职报告
2015/01/10 职场文书
团委工作总结2015
2015/04/02 职场文书
2015年安全保卫工作总结
2015/05/14 职场文书
农村结婚典礼主持词
2015/06/29 职场文书
教师理论学习心得体会
2016/01/21 职场文书
基于Redission的分布式锁实战
2022/08/14 Redis