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)
Oct 09 PHP
PHP 程序授权验证开发思路
Jul 09 PHP
discuz程序的PHP加密函数原理分析
Aug 05 PHP
JS中encodeURIComponent函数用php解码的代码
Mar 01 PHP
PHP分页详细讲解(有实例)
Oct 30 PHP
Windows下的PHP安装文件线程安全和非线程安全的区别
Apr 23 PHP
PHP反向代理类代码
Aug 15 PHP
php结合js实现点击超链接执行删除确认操作
Oct 31 PHP
Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
Mar 21 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
Oct 18 PHP
windows环境下使用Composer安装ThinkPHP5
May 18 PHP
PHP-FPM的配置与优化讲解
Mar 15 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设计模式之命令模式使用示例
2014/03/02 PHP
PHP单链表的实现代码
2016/07/05 PHP
js实现二代身份证号码验证详解
2014/11/20 Javascript
Highcharts学习之数据列
2016/08/03 Javascript
Angular2  NgModule 模块详解
2016/10/19 Javascript
ES6入门教程之let和const命令详解
2017/05/17 Javascript
js实现随机点名小功能
2017/08/17 Javascript
Vue源码学习之关于对Array的数据侦听实现
2019/04/23 Javascript
vue使用微信JS-SDK实现分享功能
2019/08/23 Javascript
layui多iframe页面控制定时器运行的方法
2019/09/05 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
Python的另外几种语言实现
2015/01/29 Python
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
Python下载指定页面上图片的方法
2016/05/12 Python
Python设置在shell脚本中自动补全功能的方法
2018/06/25 Python
在python中安装basemap的教程
2018/09/20 Python
PyQt5+requests实现车票查询工具
2019/01/21 Python
python @propert装饰器使用方法原理解析
2019/12/25 Python
python虚拟环境模块venv使用及示例
2020/03/04 Python
Django如何实现密码错误报错提醒
2020/09/04 Python
HTML5新增form控件和表单属性实例代码详解
2019/05/15 HTML / CSS
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
远程Wi-Fi宠物监控相机:Petcube
2017/04/26 全球购物
HealthElement海外旗舰店:新西兰大卖场
2018/02/23 全球购物
飞利浦西班牙官方网站:Philips西班牙
2020/02/17 全球购物
质量月活动策划方案
2014/03/10 职场文书
小学生操行评语
2014/04/22 职场文书
学校宣传标语
2014/06/18 职场文书
班级文化标语
2014/06/23 职场文书
大学生简历求职信
2014/06/24 职场文书
学校志愿者活动总结
2014/06/27 职场文书
小学优秀学生评语
2014/12/29 职场文书
给学校的建议书400字
2015/09/14 职场文书
使用react+redux实现计数器功能及遇到问题
2021/06/02 Javascript
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js
原型和原型链 prototype和proto的区别详情
2021/11/02 Javascript