zoukankan      html  css  js  c++  java
  • 一致性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";  
    
  • 相关阅读:
    Unity实现Bezier曲线的移动(三点之间的Bezier曲线的移动)
    error CS2001: Source file `Assets/Pro Standard Assets/Image Based/SaveGameData.cs' could not be found 错误
    Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) 错误
    Unity拖拽旋转2D物体
    Unity预编译
    Activity的四种launchMode
    接入华为海外SDK支付,按下home键,之后支付页面被销毁
    Android动态权限申请
    armeabi与armeabi-v7a的区别
    win7上帝模式
  • 原文地址:https://www.cnblogs.com/phpwyl/p/8808632.html
Copyright © 2011-2022 走看看