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 相关文章推荐
ADODB结合SMARTY使用~超级强
Nov 25 PHP
纯php打造的tab选项卡效果代码(不用js)
Dec 29 PHP
深入理解:XML与对象的序列化与反序列化
Jun 08 PHP
使用dump函数,给php加断点测试
Jun 25 PHP
PHP中spl_autoload_register函数的用法总结
Nov 07 PHP
PHP可变函数学习小结
Nov 29 PHP
php上传图片生成缩略图(GD库)
Jan 06 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
Mar 21 PHP
php插入含有特殊符号数据的处理方法
Nov 24 PHP
PHP htmlspecialchars() 函数实例代码及用法大全
Sep 18 PHP
laravel框架语言包拓展实现方法分析
Nov 22 PHP
PHP中SESSION过期设置
Mar 09 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 sprintf() 函数的应用(定义和用法)
2012/06/29 PHP
PHP中一个有趣的preg_replace函数详解
2018/08/15 PHP
php从数据库读取数据,并以json格式返回数据的方法
2018/08/21 PHP
laravel框架上传图片实现实时预览功能
2019/10/14 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
JS图片浏览组件PhotoLook的公开属性方法介绍和进阶实例代码
2010/11/09 Javascript
Javascript this 的一些学习总结
2012/08/31 Javascript
javascript之typeof、instanceof操作符使用探讨
2013/05/19 Javascript
JS实现简单易用的手机端浮动窗口显示效果
2016/09/07 Javascript
jquery插件bootstrapValidator表单验证详解
2016/12/15 Javascript
谈谈第三方App接入微信登录 解读
2016/12/27 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
用最少的JS代码写出贪吃蛇游戏
2018/01/12 Javascript
JS字典Dictionary类定义与用法示例
2019/02/01 Javascript
ES6顶层对象、global对象实例分析
2019/06/14 Javascript
通过vue写一个瀑布流插件代码实例
2019/09/07 Javascript
js实现双色球效果
2020/08/02 Javascript
jquery实现拖拽添加元素功能
2020/12/01 jQuery
[04:44]DOTA2英雄梦之声_第12期_矮人直升机
2014/06/21 DOTA
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python中asyncore的用法实例
2014/09/29 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
JSON文件及Python对JSON文件的读写操作
2018/10/07 Python
python 批量修改 labelImg 生成的xml文件的方法
2019/09/09 Python
Python如何实现的二分查找算法
2020/05/27 Python
解决pycharm导入本地py文件时,模块下方出现红色波浪线的问题
2020/06/01 Python
欧洲最大的笔和书写专家:The Pen Shop
2017/03/19 全球购物
美国时尚配饰品牌:Dooney & Bourke
2017/11/14 全球购物
What is view? why do we have view?
2012/06/22 面试题
评析教师个人的自我评价
2014/02/19 职场文书
售前工程师职业生涯规划
2014/03/02 职场文书
离婚协议书的书写要求
2014/09/17 职场文书
说好普通话圆梦你我他演讲稿
2014/09/21 职场文书
公司承诺书格式范文
2015/04/28 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
Golang jwt身份认证
2022/04/20 Golang