zoukankan      html  css  js  c++  java
  • Memcached 之取模与哈希算法命中率实验

    当5台memcache服务器中有一台宕机时的命中率实验。

    一、php实现代码

      1. config.php

        

            $server = array(
    		"A" => array("host" => "127.0.0.1", "port" => 11211),
    		"B" => array("host" => "127.0.0.1", "port" => 11212),
    		"C" => array("host" => "127.0.0.1", "port" => 11213),
    		"D" => array("host" => "127.0.0.1", "port" => 11214),
    		"E" => array("host" => "127.0.0.1", "port" => 11215),
    	);
    
    	$_dis = "Moder";//Consistent    
    

      2. hash.php 

        

    interface hasher {public function _hash($str);}
    	interface distribution {public function lookup($key);}
    
    	/**
    	* 	取模算法类
    	*/
    	class Moder implements hasher,distribution
    	{
    		
    		protected $_nodes = array();
    		protected $_cnt = 0;
    
    		public function _hash($str) {
    			return sprintf('%u',crc32($str)); // 把字符串转成 32 位符号整数
    		}
    
    		public function addNode($node){
    			if (in_array($node, $this->_nodes)) {
    				return true;
    			}
    			$this->_nodes[] = $node;
    			$this->_cnt += 1;
    			return true;
    		}
    
    		public function delNode($node) {
    			if (!in_array($node, $this->_nodes)) {
    				return true;
    			}
    			$key = array_search($node, $this->_nodes);
    			unset($this->_nodes[$key]);
    			$this->_cnt -= 1;
    			return true;
    		}
    
    		public function lookup($key) {
    			$key = $this->_hash($key) % $this->_cnt;
    			return $this->_nodes[$key];
    		}
    
    		public  function printNodes()
    		{
    			print_r($this->_nodes);
    		}
    	}
    
    	/*
    	$mode = new Moder();
    	$mode->addNode('a');
    	$mode->addNode('b');
    	$mode->addNode('c');
    
    	$key = "sssa";
    
    	$mode->printNodes();
    
    	echo $mode->_hash($key)."<br/>";
    
    	echo $mode->lookup($key);
    	*/
    
    
    	/**
    	*	一致性hash算法类
    	*/
    	class Consistent implements hasher,distribution{
    		protected $_nodes = array(); //服务器节点
    		protected $_postion = array();//虚拟节点
    		protected $_mul = 64; //每个节点对应 64 个虚节点
    		public function _hash($str) {
    			return sprintf('%u',crc32($str)); // 把字符串转成 32 位符号整数
    		}
    		// 核心功能
    		public function lookup($key) {
    			$point = $this->_hash($key);
    			$node = current($this->_postion); //先取圆环上最小的一个节点,当成结果
    			foreach($this->_postion as $k=>$v) {
    				if($point <= $k) 
    				{
    					$node = $v;
    					break;
    				}
    			}
    			reset($this->_postion);
    			return $node;
    		}
    		//添加节点
    		public function addNode($node) {
    			if(isset($this->nodes[$node])) {
    				return;
    			}
    			for($i=0; $i<$this->_mul; $i++) {
    				$pos = $this->_hash($node . '-' . $i);
    				$this->_postion[$pos] = $node;
    				$this->_nodes[$node][] = $pos;
    			}
    			$this->_sortPos();
    		}
    		// 循环所有的虚节点,谁的值==指定的真实节点 ,就把他删掉
    		public function delNode($node) {
    			if(!isset($this->_nodes[$node])) {
    				return;
    			}
    			foreach($this->_nodes[$node] as $k) {
    				unset($this->_postion[$k]);
    			}
    			unset($this->_nodes[$node]);
    		}
    		//将虚拟节点排序
    		protected function _sortPos() {
    			ksort($this->_postion,SORT_REGULAR);
    		}
    	}
    
    	/*
    	// 测试
    	$con = new Consistent();
    	$con->addNode('a');
    	$con->addNode('b');
    	$con->addNode('c');
    	$key = 'www.zixue.it';
    	echo '此 key 落在'.$con->lookup($key).'号节点';
    	*/
    

      3.initData.php(初始化数据)

        

            include './config.php';
    	include './hash.php';
    	set_time_limit(0);
    	$mem = new Memcache();
    	$diser = new $_dis(); 
    	foreach ($server as $key => $value) {
    		$diser->addNode($key);
    	}
    	for ($i=0; $i < 1000; $i++) { 
    		//获取服务器
    		$serv = $server[$diser->lookup("key" . $i)];
    		$mem->connect($serv['host'], $serv['port'], 2);
    		$mem->add("key".$i, "value".$i, 0, 0);
    	}
    
    	echo "full";    
    

      4.load.php (获取数据的概率)

        

            include './config.php';
    	include './hash.php';
    	set_time_limit(0);
    	$mem = new Memcache();
    	$diser = new $_dis(); 
    	foreach ($server as $key => $value) {
    		$diser->addNode($key);
    	}
    	for ($i=0; $i < 1000; $i++) { 
    		//获取服务器
    		$serv = $server[$diser->lookup("key" . $i)];
    		$mem->connect($serv['host'], $serv['port'], 2);
    		$mem->add("key".$i, "value".$i, 0, 0);
    	}
    
    	echo "full";        
    

      5.exec.php (执行)

        

            //模拟减少一台服务器
    	include './config.php';
    	include './hash.php';
    
    	$mem = new Memcache();
    	$diser = new $_dis(); 
    	foreach ($server as $key => $value) {
    		$diser->addNode($key);
    	}
    
    	//删除一台服务器
    	$diser->delNode("D");
    
    
    	for ($i=0; $i < 10000; $i++) { 
    		//获取服务器
    		$serv = $server[$diser->lookup("key" . $i)];
    		if ($serv) {
    			$mem->connect($serv['host'], $serv['port'], 2);
    			if(!$mem->get("key" . $i)){
    				$mem->add("key".$i, "value".$i, 0, 0);
    			}
    		}
    		
    		usleep(3000);
    	}     
    

    二、取模算法命中率

      如图:

        1.初始状态:

            

        2.过程中状态:

            

       3.结束状态

          

     三、哈希算法命中率

       如图:

        1.初始状态:

            

        2.过程中:

          

            3.结束状态:

          

    三、总结

      1.取模命中率为20%(1 / N),哈希命中率为80%左右((N - 1) / N)。

       2.当 memcached 节点越多时,一致性哈希算法对缓存的命中率比取模算法对缓存的命中率要高很多。

      

  • 相关阅读:
    jQuery源码dom ready分析
    jQuery的deferred对象详解(二)
    jQuery的deferred对象详解(一)
    javascript线程解释(setTimeout,setInterval你不知道的事)---转载
    前端工程精粹(二):静态资源管理与模板框架
    拒绝了对对象 'sp_sdidebug'(数据库 'master',所有者 'dbo')的 EXECUTE 权限。
    Page.User.Identity.Name获取不到结果
    水晶报表(web)表格信息展示
    Office导入导出组件权限配置汇总
    CSS hack样式兼容模式收藏
  • 原文地址:https://www.cnblogs.com/yang-2018/p/10117287.html
Copyright © 2011-2022 走看看