PHP实现的服务器一致性hash分布算法示例


Posted in PHP onAugust 09, 2018

本文实例讲述了PHP实现的服务器一致性hash分布算法。分享给大家供大家参考,具体如下:

<?php
/**
 * 对服务器进行一致性hash分布算法
 */
class HashRing
{
  private $servers = array();
  private $nodeList = array();
  private $nodeHashList = array();
  private $nodeTotalNum = 0;
  private $virtualNodeNum = 32;
  private $keyHash = '';
  public function __construct($servers)
  {
    $this->servers = $servers;
    foreach ($servers as $server) {
      for ($i = 0; $i < $this->virtualNodeNum; $i++) {
        $this->nodeList[sprintf("%u", crc32($server.'-'.$i))] = array($server, $i);
      }
    }
    ksort($this->nodeList);
    $this->nodeHashList = array_keys($this->nodeList);
  }
  private function getNodeIndex($key)
  {
    $this->keyHash = sprintf("%u", crc32($key));
    if ($this->keyHash > end($this->nodeHashList)) {
      $this->keyHash = $this->keyHash % end($this->nodeHashList);
    }
    if ($this->keyHash <= reset($this->nodeHashList)) {
      return 0;
    }
    $this->nodeTotalNum = count($this->nodeHashList);
    return $this->binaryChopIndex(0, $this->nodeTotalNum);
  }
  private function binaryChopIndex($l=0, $r=0)
  {
    if ($l < $r) {
      $avg = intval(($l+$r) / 2);
      if ($this->nodeHashList[$avg] == $this->keyHash) {
        return $avg;
      } elseif ($this->keyHash < $this->nodeHashList[$avg] && ($avg > 0)) {
        return $this->binaryChopIndex($l, $avg-1);
      } else {
        return $this->binaryChopIndex($avg+1, $r);
      }
    } else {
      return $l;
    }
  }
  public function getServersByKey($key, $num=1)
  {
    $index = $this->getNodeIndex($key);
    $server = $this->nodeList[$this->nodeHashList[$index]];
    if ($num == 1) {
      return $server[0];
    }
    if ($num >= count($this->servers)) {
      $num = count($this->servers);
    }
    $result = array($server[0]);
    for ($i=$index+1; true; $i++) {
      if ($i >= $this->nodeTotalNum) {
        $i = 0;
      }
      $nextServer = $this->nodeList[$this->nodeHashList[$i]];
      if (!in_array($nextServer[0], $result)) {
        $result[] = $nextServer[0];
      }
      if (count($result) == $num) {
        break;
      }
    }
    return $result;
  }
}
//示例
$servers = array(
  '127.0.0.1:11211',
  '127.0.0.1:11212',
  '127.0.0.1:11213',
  '127.0.0.1:11214',
  '127.0.0.1:11215'
);
$obj = new HashRing($servers);
$servers = $obj->getServersByKey('testkey', 2);
print_r($servers);
echo "\n";

运行结果:

Array
(
    [0] => 127.0.0.1:11214
    [1] => 127.0.0.1:11211
)

PHP 相关文章推荐
PHP 5.0对象模型深度探索之绑定
Sep 05 PHP
开发大型PHP项目的方法
Oct 09 PHP
PHP程序员编程注意事项
Apr 10 PHP
IIS7.X配置PHP运行环境小结
Jun 09 PHP
php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法
Mar 23 PHP
smarty的section嵌套循环用法示例
May 28 PHP
PHP中FTP相关函数小结
Jul 15 PHP
thinkPHP实现签到功能的方法
Mar 15 PHP
PHP的mysqli_stat()函数讲解
Jan 23 PHP
thinkphp5修改view到根目录实例方法
Jul 02 PHP
如何通过Apache在本地配置多个虚拟主机
Jul 29 PHP
50个优秀经典PHP算法大集合 附源码
Aug 26 PHP
PHP检查端口是否可以被绑定的方法示例
Aug 09 #PHP
php对象工厂类完整示例
Aug 09 #PHP
php闭包中使用use声明变量的作用域实例分析
Aug 09 #PHP
php生成二维码不保存服务器还有下载功能的实现代码
Aug 09 #PHP
PHP命令Command模式用法实例分析
Aug 08 #PHP
PHP耦合设计模式实例分析
Aug 08 #PHP
thinkPHP框架整合tcpdf插件操作示例
Aug 07 #PHP
You might like
某大型网络公司应聘时的笔试题目附答案
2008/03/27 PHP
PHP 上传文件大小限制
2009/07/05 PHP
深入PHP nl2br()格式化输出的详解
2013/06/05 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
Javascript 检测、添加、移除样式(className)函数代码
2009/09/08 Javascript
替代window.event.srcElement效果的可兼容性的函数
2009/12/18 Javascript
validator验证控件使用代码
2010/11/23 Javascript
JavaScript取得鼠标绝对位置程序代码介绍
2012/09/16 Javascript
jquery无缝向上滚动实现代码
2013/03/29 Javascript
javascript 禁用IE工具栏,导航栏等等实现代码
2013/04/01 Javascript
javaScript如何生成xmlhttp
2013/12/16 Javascript
js中同步与异步处理的方法和区别总结
2013/12/25 Javascript
window.showModalDialog()返回值的学习心得总结
2014/01/07 Javascript
js常用自定义公共函数汇总
2014/01/15 Javascript
深入浅出理解javaScript原型链
2015/05/09 Javascript
在Node.js中使用HTTP上传文件的方法
2015/06/23 Javascript
Angular 页面跳转时传参问题
2016/08/01 Javascript
js中判断变量类型函数typeof的用法总结
2016/08/09 Javascript
详解使用JS如何制作简单的ASCII图与单极图
2017/03/31 Javascript
vue-cli如何快速构建vue项目
2017/04/26 Javascript
深入理解vue Render函数
2017/07/19 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
requireJS模块化实现返回顶部功能的方法详解
2017/10/16 Javascript
在HTML中使用JavaScript的两种方法
2020/12/24 Javascript
[37:50]VP vs TNC Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
详解python3中socket套接字的编码问题解决
2017/07/01 Python
Django读取Mysql数据并显示在前端的实例
2018/05/27 Python
Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项
2019/10/11 Python
5 个强大的HTML5 API 函数推荐
2014/11/19 HTML / CSS
全球游戏Keys和卡片市场:GamesDeal
2018/03/28 全球购物
爷爷追悼会答谢词
2014/01/24 职场文书
个人现实表现材料
2014/02/04 职场文书
物业品质提升方案
2014/06/08 职场文书
计算机毕业生自荐信
2014/06/12 职场文书
机关党员公开承诺书
2014/08/30 职场文书