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 相关文章推荐
mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
Apr 24 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
Nov 01 PHP
PHP header函数分析详解
Aug 06 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
Jun 25 PHP
eaglephp使用微信api接口开发微信框架
Jan 09 PHP
php采集自中央气象台范围覆盖全国的天气预报代码实例
Jan 04 PHP
PHP SOCKET编程详解
May 22 PHP
PHP实现恶意DDOS攻击避免带宽占用问题方法
May 27 PHP
PHP数组操作实例分析【添加,删除,计算,反转,排序,查找等】
Dec 24 PHP
yii2 resetful 授权验证详解
May 18 PHP
php通过header发送自定义数据方法
Jan 18 PHP
php 广告点击统计代码(php+mysql)
Feb 21 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二维数组合并及去重复的方法
2015/03/04 PHP
php把数组值转换成键的方法
2015/07/13 PHP
thinkPHP5.0框架命名空间详解
2017/03/18 PHP
PHP时间戳和日期相互转换操作实例小结
2018/12/18 PHP
PHP htmlspecialchars()函数用法与实例讲解
2019/03/08 PHP
jquery 查找新建元素代码
2010/07/06 Javascript
JavaScript获取某年某月的最后一天附截图
2014/06/23 Javascript
举例讲解AngularJS中的模块
2015/06/17 Javascript
javascript实现动态导入js与css等静态资源文件的方法
2015/07/25 Javascript
coffeescript使用的方式汇总
2015/08/05 Javascript
JavaScript实战之菜单特效
2016/08/16 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
Angularjs实现下拉框联动的示例代码
2017/08/22 Javascript
使用vue的transition完成滑动过渡的示例代码
2018/06/25 Javascript
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
一份超级详细的Vue-cli3.0使用教程【推荐】
2018/11/15 Javascript
JQuery样式操作、click事件以及索引值-选项卡应用示例
2019/05/14 jQuery
深入了解JavaScript 私有化
2019/05/30 Javascript
vue实现购物车功能(商品分类)
2020/04/20 Javascript
Python中列表、字典、元组数据结构的简单学习笔记
2016/03/20 Python
详解Python中heapq模块的用法
2016/06/28 Python
pytorch中的卷积和池化计算方式详解
2020/01/03 Python
python时间与Unix时间戳相互转换方法详解
2020/02/13 Python
详解vscode实现远程linux服务器上Python开发
2020/11/10 Python
英国设计师泳装、沙滩装和比基尼在线精品店:Beach Cafe
2019/08/28 全球购物
惠而浦美国官网:Whirlpool.com
2021/01/19 全球购物
钳工实习自我鉴定
2013/09/19 职场文书
文秘人员工作职责
2014/01/31 职场文书
优秀辅导员事迹材料
2014/02/16 职场文书
《天安门广场》教学反思
2014/04/23 职场文书
小学向国旗敬礼活动方案
2014/09/27 职场文书
百年孤独读书笔记
2015/06/29 职场文书
干货:企业内部人才推荐奖励方案!
2019/07/09 职场文书
Nginx中break与last的区别详析
2021/03/31 Servers
Nginx工作原理和优化总结。
2021/04/02 Servers
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android