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 相关文章推荐
Smarty模板快速入门
Jan 04 PHP
PHP下打开URL地址的几种方法小结
May 16 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
Dec 05 PHP
浅析php header 跳转
Jun 17 PHP
php实现文件下载代码分享
Aug 19 PHP
php将数组存储为文本文件方法汇总
Oct 28 PHP
详解WordPress中简码格式标签编写的基本方法
Dec 22 PHP
PHP设置Cookie的HTTPONLY属性方法
Feb 09 PHP
php插件Xajax使用方法详解
Aug 31 PHP
浅谈laravel中的关联查询with的问题
Oct 10 PHP
Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示例
Oct 12 PHP
让你的PHP,APACHE,NGINX支持大文件上传
Mar 09 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
不用数据库的多用户文件自由上传投票系统(2)
2006/10/09 PHP
PHP文件大小格式化函数合集
2014/03/10 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
2015/08/21 PHP
php计划任务之验证是否有多个进程调用同一个job的方法
2015/12/07 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
在线游戏大家来找茬II
2006/09/30 Javascript
中国地区三级联动下拉菜单效果分析
2012/11/15 Javascript
js获取input标签的输入值实现代码
2013/08/05 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
2014/05/28 Javascript
jQuery给多个不同元素添加class样式的方法
2015/03/26 Javascript
Jquery网页内滑动缓冲导航的实现代码
2015/04/05 Javascript
深入学习jQuery Validate表单验证(二)
2016/01/18 Javascript
javascript十六进制数字和ASCII字符之间的转换方法
2016/12/27 Javascript
Vuex 入门教程
2018/01/10 Javascript
Vue单页应用引用单独的样式文件的两种方式
2018/03/30 Javascript
Vue-router 切换组件页面时进入进出动画方法
2018/09/01 Javascript
js实现无限瀑布流实例方法
2019/09/16 Javascript
Vue切换div显示隐藏,多选,单选代码解析
2020/07/14 Javascript
多个Vue项目部署到服务器的步骤记录
2020/10/22 Javascript
vue使用vant中的checkbox实现全选功能
2020/11/17 Vue.js
让python json encode datetime类型
2010/12/28 Python
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
python实现傅里叶级数展开的实现
2018/07/21 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
TensorFlow实现指数衰减学习率的方法
2020/02/05 Python
Python字符串查找基本操作代码案例
2020/10/27 Python
Python GUI库Tkiner使用方法代码示例
2020/11/27 Python
CSS3实现任意图片lowpoly动画效果实例
2017/05/11 HTML / CSS
three.js模拟实现太阳系行星体系功能
2019/09/03 HTML / CSS
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
自我检讨书怎么写
2015/05/07 职场文书
党务工作者主要事迹材料
2015/11/03 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书
Python机器学习之逻辑回归
2021/05/11 Python