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 相关文章推荐
第1次亲密接触PHP5(2)
Oct 09 PHP
PHP实现的功能是显示8条基色色带
Oct 09 PHP
php设计模式小结
Feb 15 PHP
php使用filter过滤器验证邮箱 ipv6地址 url验证
Dec 25 PHP
使用新浪微博API的OAuth认证发布微博实例
Mar 27 PHP
PHP判断JSON对象是否存在的方法(推荐)
Jul 06 PHP
php is_executable判断给定文件名是否可执行实例
Sep 26 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
Nov 14 PHP
php图片合成方法(多张图片合成一张)
Nov 25 PHP
PHPExcel实现表格导出功能示例【带有多个工作sheet】
Jun 13 PHP
PHP设计模式之模板方法模式实例浅析
Dec 20 PHP
Yii框架响应组件用法实例分析
Sep 04 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
php中文字符截取防乱码
2008/03/28 PHP
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
PHP获取MSN好友列表类的实现代码
2013/06/23 PHP
php验证身份证号码正确性的函数
2016/07/20 PHP
Laravel学习教程之IOC容器的介绍与用例
2017/08/15 PHP
php关联数组与索引数组及其显示方法
2018/03/12 PHP
JS对文本框值的判断示例
2014/03/10 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
jquery插件推荐浏览器嗅探userAgent
2014/11/09 Javascript
javascript中typeof操作符和constucor属性检测
2015/02/26 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
JavaScript中constructor()方法的使用简介
2015/06/05 Javascript
JavaScript中的fontsize()方法使用详解
2015/06/08 Javascript
jQuery购物车插件jsorder用法(支持后台处理程序直接转换成DataTable处理)
2016/06/08 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
细说Vue组件的服务器端渲染的过程
2019/05/30 Javascript
解决layui 三级联动下拉框更新时回显的问题
2019/09/03 Javascript
vue swipeCell滑动单元格(仿微信)的实现示例
2020/09/14 Javascript
[04:26]2014DOTA2西雅图国际邀请赛 总决赛TOPPLAY
2014/07/22 DOTA
python实现根据窗口标题调用窗口的方法
2015/03/13 Python
Python实现连接postgresql数据库的方法分析
2017/12/27 Python
python抓取文件夹的所有文件
2018/02/27 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
2018/05/05 Python
如何通过雪花算法用Python实现一个简单的发号器
2019/07/03 Python
pandas实现将日期转换成timestamp
2019/12/07 Python
Python requests接口测试实现代码
2020/09/08 Python
马来西亚与新加坡长途巴士售票网站:BusOnlineTicket.com
2018/11/05 全球购物
如何处理简单的PHP错误
2015/10/14 面试题
this关键字的含义
2015/04/08 面试题
财务出纳员岗位职责
2013/11/26 职场文书
关于人生的感言
2014/01/17 职场文书
《夜晚的实验》教学反思
2014/02/19 职场文书
司法所长先进事迹
2014/06/02 职场文书
2016廉洁从业学习心得体会
2016/01/19 职场文书
如何拟写通知正文?
2019/04/02 职场文书
2019军训心得体会
2019/06/27 职场文书