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 相关文章推荐
第五节 克隆 [5]
Oct 09 PHP
建立文件交换功能的脚本(三)
Oct 09 PHP
服务器端解压缩zip的脚本
Dec 22 PHP
php递归列出所有文件和目录的代码
Sep 10 PHP
PHP逐行输出(ob_flush与flush的组合)
Feb 04 PHP
weiphp微信公众平台授权设置
Jan 04 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
Nov 07 PHP
thinkPHP批量删除的实现方法分析
Nov 09 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
PHP实现的折半查找算法示例
Dec 19 PHP
PHP框架Laravel中使用UUID实现数据分表操作示例
May 30 PHP
php获取是星期几的的一些常用姿势
Dec 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
苏联队长,苏联超人蝙蝠侠,这些登场的“山寨”英雄真的很严肃
2020/04/09 欧美动漫
php 中include()与require()的对比
2006/10/09 PHP
php 获取页面中指定内容的实现类
2014/01/23 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
2015/11/27 PHP
原生php实现excel文件读写的方法分析
2018/04/25 PHP
php和asp语法上的区别总结
2019/05/12 PHP
JavaScript 模仿vbs中的 DateAdd() 函数的代码
2007/08/13 Javascript
jQuery toggle()设置CSS样式
2009/11/05 Javascript
JavaScript中json使用自己总结
2013/08/13 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
jQuery Mobile框架中的表单组件基础使用教程
2016/05/17 Javascript
jQuery Tree Multiselect使用详解
2017/05/02 jQuery
Angular 2.x学习教程之结构指令详解
2017/05/25 Javascript
JS+HTML5实现图片在线预览功能
2017/07/22 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
如何手写简易的 Vue Router
2020/10/10 Javascript
[04:27]2014DOTA2国际邀请赛 NAVI战队官方纪录片
2014/07/21 DOTA
[33:15]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VP VS Mineski
2018/03/31 DOTA
[05:11]TI9战队采访——VIRTUSPRO
2019/08/22 DOTA
Python线程详解
2015/06/24 Python
浅谈django model的get和filter方法的区别(必看篇)
2017/05/23 Python
pygame实现简易飞机大战
2018/09/11 Python
python把转列表为集合的方法
2019/06/28 Python
python动态文本进度条的实例代码
2020/01/22 Python
Pycharm生成可执行文件.exe的实现方法
2020/06/02 Python
Python中Pyspider爬虫框架的基本使用详解
2021/01/27 Python
英国在线珠宝店:The Jewel Hut
2017/03/20 全球购物
英国蛋糕装饰用品一站式商店:Craft Company
2019/03/18 全球购物
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
美容院营销方案
2014/03/05 职场文书
技术支持岗位职责
2015/02/13 职场文书
军训通讯稿范文
2015/07/18 职场文书
公司仓库管理制度
2015/08/04 职场文书
sql中mod()函数取余数的用法
2021/05/29 SQL Server
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript
vue ant design 封装弹窗表单的使用
2022/06/01 Vue.js