首页 > 开发 > PHP > 正文

PHP一致性hash分布式算法封装类定义与用法示例

2024-05-04 22:42:29
字体:
来源:转载
供稿:网友

本文实例讲述了PHP一致性hash分布式算法封装类定义与用法。分享给大家供大家参考,具体如下:

一、无虚拟节点实现

<?php/** * 一致性hash分布式算法 * @param $key * @return int * 实现步骤 * 1.先将0~ 是32位最大带符号整数(0x7FFFFFFF) 想象成一个闭环 * 2.将服务器列表通过hash算法分布在 圆环之中 * 3.将key值也分布在圆环之中 * 4.通过_isSorted判断服务器是否需要进行倒序排序 排序后遍历服务器 找到最近的服务器 返回 * hash算法是不保证平衡的 为了尽量保证平衡性 我们应该加入虚拟节点数 将一个服务器节点虚拟化成为多个 较大程度上保证了平衡性 */class FlexiHash{  private $_serverList = array();  private $_isSorted = false;  private $_virtual_node_num = 20;//虚拟节点数 服务器越少 增加的虚拟节点数应该越多  //通过hash算法返回一个整数值  protected function myHash($key){    $md5 = substr(md5($key),0,8);    $seed = 31; //种子值    $hash=0;    for($i=0;$i<8;$i++){      $hash = $hash*$seed+ord($md5{$i}); //ord 返回ascii值      $i++;    }    return $hash&0x7FFFFFFF; //0x7FFFFFFF表示最大值  }  //添加服务器  function addServer($server){    $hash =$this->myHash($server. '#1');    if(!isset($this->_serverList[$hash])) {      for ($i = 1; $i <= $this->_virtual_node_num; $i++) {        $hash = $this->myHash($server . '#' . $i);        $this->_serverList[$hash] = $server;      }    }    $this->_isSorted = false;    return true;  }  //删除服务器  function removeServer($server){    for ($i = 1; $i <= $this->_virtual_node_num; $i++) {      $hash = $this->myHash($server . '#' . $i);      unset($this->_serverList[$hash]);    }    $this->_isSorted = false;    return true;  }  //获取服务器  function lookup($key){    $hash =$this->myHash($key);    if(!$this->_isSorted){      krsort($this->_serverList,SORT_NUMERIC);      $this->_isSorted = true;    }    foreach($this->_serverList as $pos=>$server){      if($hash >= $pos) return $server;    }    return end($this->_serverList);  }  public function getServerList(){    krsort($this->_serverList,SORT_NUMERIC);    return $this->_serverList;  }}//demo test$hserver = new FlexiHash();//添加服务器$hserver->addServer('192.168.1.1');$hserver->addServer('192.168.1.2');$hserver->addServer('192.168.1.3');$hserver->addServer('192.168.1.4');$hserver->addServer('192.168.1.5');$key1='Key1111';$key2='Key2222';$key2='Key3333';$key2='Key4444';$key2='Key5555';$key2='Key6666';echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;echo "================================================".PHP_EOL;//移除服务器 key值将自动转义到下一台服务器$hserver->removeServer('192.168.1.4');echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;echo "================================================".PHP_EOL;//恢复故障服务器 key值将恢复原来服务器$hserver->addServer('192.168.1.4');echo "save key1 in server: ".$hserver->lookup($key1).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key2).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key3).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key4).PHP_EOL;echo "save key1 in server: ".$hserver->lookup($key5).PHP_EOL;echo "save key2 in server: ".$hserver->lookup($key6).PHP_EOL;            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表