zoukankan      html  css  js  c++  java
  • 一致性hash

      1 <?php
      2 /**
      3  * 分布式缓存部署方案
      4  * 当有1台cache服务器不能满足我们的需求,我们需要布置多台来做分布式服务器,但是
      5  * 有个问题,怎么确定一个数据应该保存到哪台服务器上呢?
      6  * 有两种方案,第一种普通hash分布,第二种一致性哈希分布
      7  *
      8  * 普通hash分布
      9  * 首先将key处理为一个32位字符串,取前8位,在经过hash计算处理成整数并返回,然后映射到其中一台服务器
     10  * $servers[mhash($key) % 2] 这样得到其中一台服务器的配置,利用这个配置完成分布式部署
     11  * 在服务器数量不发生变化的情况下,普通hash分布可以很好的运作,当服务器的数量发生变化,问题就来了
     12  * 试想,增加一台服务器,同一个key经过hash之后,与服务器取模的结果和没增加之前的结果肯定不一样,这就导致了,之前保存的数据丢失
     13  *
     14  * 一致性哈希算法
     15  * 优点:在分布式的cache缓存中,其中一台宕机,迁移key效率最高
     16  * 将服务器列表进行排序,根据mHash($key) 匹配相邻服务器
     17  */
     18  
     19 /**
     20  * hash算法
     21  * @param string $key
     22  * @return int
     23  */
     24 function mHash($key)
     25 {
     26     $md5 = substr(md5($key), 0, 8);
     27     $seed = 31;
     28     $hash = 0;
     29      
     30     for($i = 0; $i < 8; $i++){
     31         $hash = $hash * $seed + ord($md5{$i});
     32         $i++;
     33     }
     34     return $hash & 0x7FFFFFFF;
     35 }
     36  
     37 class FlexiHash
     38 {
     39     // 服务器列表
     40     private $serverList = array();
     41     // 服务器列表key数组
     42      private $serverKeys = array();
     43     // 是否排序
     44     private $isSorted = false;
     45      
     46     /**
     47      * 添加服务器
     48      * @param string $server
     49      * @return boolean
     50      */
     51     function addServer($server)
     52     {
     53         $hash = mHash($server);
     54         if (!isset($this->serverList[$hash])) {
     55             $this->serverList[$hash] = $server;
     56         }
     57         $this->isSorted = false;
     58         return true;
     59     }
     60      
     61     /**
     62      * 移除服务器
     63      * @param string $server
     64      * @return boolean
     65      */
     66     function removeServer($server)
     67     {
     68         $hash = mHash($server);
     69         if (isset($this->serverList[$hash])) {
     70             unset($this->serverList[$hash]);
     71         }
     72         $this->isSorted = false;
     73         return true;
     74     }
     75      
     76     /**
     77      * 根据$key逆时针查找相邻的服务器
     78      * @param string $key
     79      * @return string
     80      */
     81     function lookup($key)
     82     {
     83         $hash = mHash($key);
     84         // 对服务器列表逆排序
     85         if (!$this->isSorted) {
     86             krsort($this->serverList, SORT_NUMERIC);
     87             $this->isSorted = true;
     88               $this->serverKeys = array_keys($this->serverList);
     89         }
     90         // 查找相邻的数据
     91         foreach ($this->serverList as $pos => $server) {
     92             if ($hash >=  $pos) return $server;
     93         }
     94         // 找不到,返回最后一个
     95         return $this->serverList[$this->serverKeys[count($this->serverList) - 1]];
     96     }
     97 }
     98  
     99 $hserver = new FlexiHash();
    100 $hserver->addServer('192.168.1.1');
    101 $hserver->addServer('192.168.1.2');
    102 $hserver->addServer('192.168.1.3');
    103 $hserver->addServer('192.168.1.4');
    104 $hserver->addServer('192.168.1.5');
    105 $hserver->addServer('192.168.1.6');
    106  
    107 echo "<pre>";
    108 for($i=0; $i < 10000; $i++) {
    109   $t = $hserver->lookup('key'.$i);
    110   $arr[] = $t;
    111 }
    112 print_r($arr);
  • 相关阅读:
    心情日记:【原创诗歌】怆情吟
    心情日记:2008年3月3日 奶奶去世
    心情日记:健身日记
    金融基础概念期货
    FXDD点值获利计算
    外汇基础概念汇率
    报告论文:是学生都copy下来,现在不用,将来绝对要用(转)
    情感日记:毕业临走物语
    美元为什么坚挺
    英特尔首席技术官:人机智能鸿沟将于2050年消失
  • 原文地址:https://www.cnblogs.com/zrp2013/p/4532723.html
Copyright © 2011-2022 走看看