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:风雨欲来 路在何方?
Oct 09 PHP
PHP学习之PHP变量
Oct 09 PHP
PHP 可阅读随机字符串代码
May 26 PHP
php中的注释、变量、数组、常量、函数应用介绍
Nov 16 PHP
PHP中使用cURL实现Get和Post请求的方法
Mar 13 PHP
php 判断数组是几维数组
Mar 20 PHP
ThinkPHP文件上传实例教程
Aug 22 PHP
老版本PHP转义Json里的特殊字符的函数
Jun 08 PHP
PHP+Session防止表单重复提交的解决方法
Apr 09 PHP
PHP中md5()函数的用法讲解
Mar 30 PHP
php简单计算权重的方法示例【适合抽奖类应用】
Jun 10 PHP
Laravel 读取 config 下的数据方法
Oct 13 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 截取字符串 分别适合GB2312和UTF8编码情况
2009/02/12 PHP
PHP判断密码强度的方法详解
2017/05/26 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
php提取微信账单的有效信息
2018/10/01 PHP
关于laravel后台模板laravel-admin select框的使用详解
2019/10/03 PHP
基于jquery的Repeater实现代码
2010/07/17 Javascript
动态创建样式表在各浏览器中的差异测试代码
2011/09/13 Javascript
jquery乱码与contentType属性设置问题解决方案
2013/01/07 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
2014/05/14 Javascript
jQuery 获取兄弟元素的几种不错方法
2014/05/23 Javascript
js实现DOM走马灯特效的方法
2015/01/21 Javascript
在jQuery中使用$而避免跟其它库产生冲突的方法
2015/08/13 Javascript
浅析$.getJSON异步请求和同步请求
2016/06/06 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
vue.js组件之间传递数据的方法
2017/07/10 Javascript
angular中不同的组件间传值与通信的方法
2017/11/04 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
解决layui中table异步数据请求不支持自定义返回数据格式的问题
2018/08/19 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
python实现模拟按键,自动翻页看u17漫画
2015/03/17 Python
python编程开发之日期操作实例分析
2015/11/13 Python
深入理解python中的select模块
2017/04/23 Python
Python 统计字数的思路详解
2018/05/08 Python
对Python 语音识别框架详解
2018/12/24 Python
Python制作动态字符图的实例
2019/01/27 Python
linux环境中没有网络怎么下载python
2019/07/07 Python
春节到了 教你使用python来抢票回家
2020/01/06 Python
详解如何在登录过期后跳出Ifram框架
2020/09/10 HTML / CSS
公司营业员的工作总结自我评价
2013/10/05 职场文书
加拿大留学自荐信
2014/01/28 职场文书
《最后的姿势》教学反思
2014/02/27 职场文书
人事任命书格式
2014/06/05 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
自查自纠工作总结
2014/10/15 职场文书
教师正风肃纪剖析材料
2014/10/20 职场文书