zoukankan      html  css  js  c++  java
  • memcached 分布式 一致性hash算法demo

    一致性Hash分布算法分4个步骤:
    步骤1:将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象。
    步骤2:通过Hash函数把KEY处理成整数。这样就可以在环上找到一个位置与之对应。
    步骤3:把Memcached服务器群映射到环上,使用Hash函数处理服务器对应的IP地址即可。
    步骤4:把数据映射到Memcached服务器上。查找一个KEY对应的Memcached服务器位置的方法如下:从当前KEY的位置,沿着圆环顺时针方向出发,查找位置离得最近的一台Memcached服务器,并将KEY对应的数据保存在此服务器上。

    代码实例:

    <?php
    /**
     * 一致性Hash分布
     * 天涯PHP博客
     * http://blog.phpha.com
     */
    class FlexiHash{
    	//服务器列表
    	private $serverList = array();
    	//记录是否已经排序
    	private $isSorted = FALSE;
    	//添加一台服务器
    	public function addServer($server){
    		$hash = $this->mHash($server);
    		if(!isset($this->serverList[$hash])){
    			$this->serverList[$hash] = $server;
    		}
    		//需要重新排序
    		$this->isSorted = FALSE;
    		return TRUE;
    	}
    	//移除一台服务器
    	public function removeServer($server){
    		$hash = $this->mHash($server);
    		if(isset($this->serverList[$hash])){
    			unset($this->serverList[$hash]);
    		}
    		//需要重新排序
    		$this->isSorted = FALSE;
    		return TRUE;
    	}
    	//在当前服务器列表查找合适的服务器
    	public function lookup($key){
    		$hash = $this->mHash($key);
    		//先进行倒序排序操作
    		if(!$this->isSorted){
    			krsort($this->serverList, SORT_NUMERIC);
    			$this->isSorted = TRUE;
    		}
    		//圆环上顺时针方向查找当前KEY紧邻的一台服务器
    		foreach($this->serverList as $pos => $server){
    			if($hash >= $pos)	return $server;
    		}
    		//没有找到则返回顺时针方向最后一台服务器
    		return $this->serverList[count($this->serverList) - 1];
    	}
    	//Hash函数
    	private function mHash($key){
    		$md5 = substr(md5($key), 0, 8);
    		$seed = 31;
    		$hash = 0;
    		for($i = 0; $i < 8; $i++){
    			$hash = $hash * $seed + ord($md5{$i});
    			$i++;
    		}
    		return $hash & 0x7FFFFFFF;
    	}
    }
    ?>
    

      

    测试:

    <?php
    /**
     * 一致性Hash分布测试代码
     * 天涯PHP博客
     * http://blog.phpha.com
     */
    $hserver = new FlexiHash();
    //初始5台服务器
    $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");
    echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
    echo "save key2 in server: ", $hserver->lookup('key2'), "<br/>";
    echo '===============================================<br/>';
    //移除1台服务器
    $hserver->removeServer("192.168.1.4");
    echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
    echo "save key2 in server: ", $hserver->lookup('key2'), "<br/>";
    echo '===============================================<br/>';
    //添加1台服务器
    $hserver->addServer('192.168.1.6');
    echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
    echo "save key2 in server: ", $hserver->lookup('key2');
    ?>

    //测试结果如下: save key1 in server: 192.168.1.4 save key2 in server: 192.168.1.2 ================================== save key1 in server: 192.168.1.3 save key2 in server: 192.168.1.2 ================================== save key1 in server: 192.168.1.3 save key2 in server: 192.168.1.2

      

  • 相关阅读:
    C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)
    Linux 共享库(动态库)
    虚幻4
    从头认识java-16.5 nio的数据转换
    JavaScript实现禁用键盘和鼠标的点击事件
    Codeforces Round #277.5 (Div. 2)部分题解
    iOS-WKWebView使用
    我学cocos2d-x (三) Node:一切可视化对象的祖先
    Android Studio右下角不显示当前branch名称
    Neo4j简单的样例
  • 原文地址:https://www.cnblogs.com/icyy/p/5198998.html
Copyright © 2011-2022 走看看