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
初探PHP5
Oct 09 PHP
PHP 简单日历实现代码
Oct 28 PHP
php printf输出格式使用说明
Dec 05 PHP
基于PHP常用函数的用法详解
May 10 PHP
PHP使用CURL获取302跳转后的地址实例
May 04 PHP
CI框架在CLI下执行占用内存过大问题的解决方法
Jun 17 PHP
Yii输入正确验证码却验证失败的解决方法
Jun 06 PHP
php如何把表单内容提交到数据库
Jul 08 PHP
Laravel框架实现多个视图共享相同数据的方法详解
Jul 09 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
Apr 13 PHP
解决Laravel使用验证时跳转到首页的问题
Nov 17 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游戏编程25个脚本代码
2011/02/08 PHP
360通用php防护代码(使用操作详解)
2013/06/18 PHP
一个PHP的ZIP压缩类分享
2014/05/04 PHP
程序员的表白神器“520”大声喊出来
2016/05/20 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
JS实现浏览器菜单命令
2006/09/05 Javascript
firefox中JS读取XML文件
2006/12/21 Javascript
统计jQuery中各字符串出现次数的工具
2012/05/03 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
2012/10/11 Javascript
JS 获取鼠标左右键的键值方法
2014/10/11 Javascript
Javascript访问器属性实例分析
2014/12/30 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
微信小程序 实例开发总结
2017/04/26 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
nuxt+axios解决前后端分离SSR的示例代码
2017/10/24 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
karma+webpack搭建vue单元测试环境的方法示例
2018/05/24 Javascript
用vue快速开发app的脚手架工具
2018/06/11 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
jquery将json转为数据字典的实例代码
2019/10/11 jQuery
Node.js Domain 模块实例详解
2020/03/18 Javascript
微信小程序连接服务器展示MQTT数据信息的实现
2020/07/14 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
2020/10/29 Javascript
高性能web服务器框架Tornado简单实现restful接口及开发实例
2014/07/16 Python
Python初学者需要注意的事项小结(python2与python3)
2018/09/26 Python
Python过滤txt文件内重复内容的方法
2018/10/21 Python
对python:threading.Thread类的使用方法详解
2019/01/31 Python
关于python 跨域处理方式详解
2020/03/28 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
物业电工岗位职责
2013/11/20 职场文书
巾帼文明岗申报材料
2014/05/01 职场文书
生日祝酒词大全
2015/08/10 职场文书
mongoDB数据库索引快速入门指南
2022/03/23 MongoDB
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
2022/04/24 Vue.js