加入收藏 | 设为首页 | 会员中心 | 我要投稿 唐山站长网 (https://www.0315zz.com.cn/)- 数据安全、数据开发、文字识别、图像处理、媒体智能!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Memcached分布式部署方案设计

发布时间:2022-07-05 09:28:43 所属栏目:PHP教程 来源:互联网
导读:一台Memcache通常不能满足我们的需求,这就需要分布式部署。Memcached分布式部署方案通常会采用两种方式,一种是普通Hash分布,一种是一致性Hash分布,本篇将以PHP作为客户端,来分析两种方案. 一、普通Hash分布: ?php function test($key=name){ $md5 = substr(m
  一台Memcache通常不能满足我们的需求,这就需要分布式部署。Memcached分布式部署方案通常会采用两种方式,一种是普通Hash分布,一种是一致性Hash分布,本篇将以PHP作为客户端,来分析两种方案.
 
  一、普通Hash分布:
 
  <?php
  function test($key='name'){
      $md5 = substr(md5($key), 0, 8);
      $seed = 31;
      $hash = 0;
      for($i=0; $i<8; $i++){
          $hash = $hash * $seed + ord($md5[$i]);
      }
      return $hash & 0x7FFFFFFF;
  }
  $memcacheList = array(
          array('host'=>'192.168.1.2', 'port'=>6379),
          array('host'=>'192.168.1.3', 'port'=>6379),
          array('host'=>'192.168.1.4', 'port'=>6379),
          array('host'=>'192.168.1.5', 'port'=>6379),
  );
  $key = 'username';
  $value = 'lane';
  //根据KEY获取hash
  $hash = $this->test($key);
  $count = count($memcacheList);
  $memcache = $memcacheList[$hash % $count];
  $mc = new Memcached($memcache);
  $mc->set($key, $value);
  ?>
  代码很简单,一个Hash函数,根据所需要的key,将他md5后取前8位,然后经过Hash算法返回一个整数,将这个整数对服务器总数求模,得到的就是服务器列表的编号,这种方式的缺点是服务器数量改变后,同一个key不同hash,将取不到值了.
 
  二、一致性Hash分布
 
  一致性Hash尽管也会造成数据的丢失,但是损失是最小的,将2的32次方-1想象成一个圆环,服务器列表在上面排列,根据key通过hash算法求得在圆环上的位置,那么所需要的服务器的位置在key的位置前面最近的一个(顺时针).
 
  <?php
  class FlexiHash{
      //服务器列表
      private $serverList = array();
      //是否排序
      private $isSort = false;
      /**
       * Description: Hash函数,将传入的key以整数形式返回
       * @param string $key
       * @return int
       */
      private 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]);
          }
          return $hash & 0x7FFFFFFF;
      }
      /**
       * Description: 添加新服务器
       * @param $server
       */
      public function addServer($server){
          $hash = $this->myHash($server);
          if(!isset($this->serverList[$hash])){
              $this->serverList[$hash] = $server;
          }
          $this->isSort = false;
          return true;
      }
      /**
       * Description: 删除指定服务器
       * @param $server
       * @return bool
       */
      public function removeServer($server){
          $hash = $this->myHash($server);
          if(isset($this->serverList[$hash])){
              unset($this->serverList[$hash]);
          }
          $this->isSort = false;
          return true;
      }
      /**
       * Description: 根据要操作的KEY返回一个操作的服务器信息
       * @param $key
       * @return mixed
       */
      public function lookup($key){
          //将指定的KEYhash出一个整数
          $hash = $this->myHash($key);
          if($this->isSort !== true){
              krsort($this->serverList);
              $this->isSort = false;
          }
          foreach($this->serverList as $key=>$server){
              if($key <= $hash){
                  return $server;
              }
          }
          return array_pop($this->serverList);
      }  //开源软件:phpfensi.com
  }
  //使用方法
  $mc = new FlexiHash();
  $mc->addServer('192.168.1.2');
  $mc->addServer('192.168.1.3');
  $mc->addServer('192.168.1.4');
  $mc->addServer('192.168.1.5');
  echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key1').'<br>';
  echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key2').'<br>';
  echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key3').'<br>';
  echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key4').'<br>';
  echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key5').'<br>';
  ?>
 

(编辑:唐山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读