zoukankan      html  css  js  c++  java
  • memcached 分布式聚类算法

              memcached 分布式集群,该决定必须书面开发商自己。和redis 由分布式server决定。上 memcached 有两个选项用于分布式。第一个是:模运算

    另一种是:一致性hash 分布式算法。以下我就这两种算法简介一下。


            一、取模算法:

            取模算法是不靠谱的算法,当有n 台server,突然一台server突然down 掉了。memcached 的命中率仅仅有1/n-1。结果是怎么来的,自己想想吧。比方有8台memchached 

    server,0,1,2,3。4,5。6,7,8  这8个数字存入到memcached server,突然有一台memcached serverdown 掉了。

    我们用取模法,从memcached server取值。

    发现仅仅有0。1,2。3,4,5,6。56 这些数被7,8取模的值是一样的。也就是说这么写能被命中。

    也就得出了结论 n/n(n-1) 个数可以被命中。相同也得出结论server集群越大,

    命中率也就越低。

    这中算法直接pass 掉。

    并且命中率会无限趋进于0。


       二、一致性hash 分布式算法:

            介绍这样的算法。首先我引进一个概念是虚拟节点。虚拟节点也就是说在没台memcached server虚拟非常多节点。并算出每一个节点的hash 值。

    存key 时,同一时候计算出key 的hash 

    值,当key的hash 值,接近或等于某个节点的hash 值,就放到某个 memcached server。当某个memcached serverdown 掉后。其它server共同承担这台server的压力。

    以下是我的一段代码:


    <?php
       /*
        memcached 一致性hash分布式算法
       */
       interface hash{
    	   public function _hash($str);   // hash 算法
       }
    
       interface distribution{
    		public function _lookup($key);  
       }
    
       class contents implements hash,distribution{
    		public $address_array=array();
    		public function _hash($str){
    			return sprintf("%u",crc32($str));
    		}
    		public function _lookup($key){   //通过key 找到server
    			$look_key=$this->_hash($key);
    			$current_key=current($this->address_array);
    			foreach($this->address_array as $key=>$value){
    				if($look_key<=$key){
    					$current_key=$key;
    					break;
    				}
    			}
    			return $value;
    		}
    		public function _address($node){  // 虚拟节点
    			for($i=0;$i<64;$i++){
    				$key=$this->_hash($node.'_'.$i);
    				$this->address_array[$key]=$node;	
    			}
    			$this->_sortkey();
    		}
    		public function _sortkey(){   // 对hash 后的值排序
    		    ksort($this->address_array,SORT_REGULAR);
    		}
    
    		public function delnode($node){   // down 掉了某台server
    		  $new_address=array_diff_key($this->address_array,array_flip(array_keys($this->address_array,$node)));
    		  $this->address_array=$new_address;
    		  return $new_address;
    		}
       }

    以下另一段模拟降低一台memcached server的代码:

     

    <?php
         require_once 'config.php';      //载入配置文件
         require_once 'distribute.php';  //载入一致hash 
         $distribute=new contents();
    
    	 //循环加入server
         foreach($mem_array as $key=>$value){
          $distribute->_address($key);
        }
    
    	 //降低一台server
    	 $distribute->delnode('B');
    
    
         for($i=0;$i<10000;$i++){
    	   $key='key'.sprintf("%04d",$i);
           $memca_key=$distribute->_lookup($key);
    	   $memca_party=$mem_array[$memca_key];
           $memcache = memcache_connect($memca_party['ip'],$memca_party['port']);
    	   if(!$memcache->get($key)){
    		   $memcache->add($key,'value'.$i,0,0);
    	   }
    	   $memcache->close();
    
        }

         以下是memcached server的配置文件

       

     /*
       memcached 的配置文件
     */
     $mem_array=array(
         'A'=>array('ip'=>'127.0.0.1','port'=>'11211'),
    	 'B'=>array('ip'=>'127.0.0.1','port'=>'11212'),
    	 'C'=>array('ip'=>'127.0.0.1','port'=>'11213'),
    	 'D'=>array('ip'=>'127.0.0.1','port'=>'11214')
      );

    以下是计算memcached 的命中率:

    <?php 
       
       require_once 'config.php';  //载入配置文件
       $int_get=0;
       $int_hits=0;
       $rand=1;
       foreach($mem_array as $value){
    	  $memcache = memcache_connect($value['ip'],$value['port']);
    	  $statistics =$memcache->getStats();
    	  $int_get += $statistics['cmd_get'];
    	  $int_hits += $statistics['get_hits'];
       }
       if($int_get==0){
    	  echo  $rand;
    	  return true;
       }
       $rand=$int_hits/$int_get;
       echo $rand;

    以下是highcharts 插件统计的 memcached 命中率



    <!DOCTYPE HTML>
    <html>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    		<title>Highcharts Example</title>
    
    		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    		<style type="text/css">
           ${demo.css}
    		</style>
    		<script type="text/javascript">
    $(function () {
        $(document).ready(function () {
            Highcharts.setOptions({
                global: {
                    useUTC: false
                }
            });
    
            $('#container').highcharts({
                chart: {
                    type: 'spline',
                    animation: Highcharts.svg, // don't animate in old IE
                    marginRight: 10,
                    events: {
                        load: function () {
    
                            // set up the updating of the chart each second
                            var series = this.series[0];
                            setInterval(function () {
                                var x = (new Date()).getTime(), // current time
                                    y = parseFloat($.ajax({url:'hit.php',async:false}).responseText);
                                series.addPoint([x, y], true, true);
                            }, 1000);
                        }
                    }
                },
                title: {
                    text: 'memcached 命中率'
                },
                xAxis: {
                    type: 'datetime',
                    tickPixelInterval: 150
                },
                yAxis: {
                    title: {
                        text: 'Value'
                    },
                    plotLines: [{
                        value: 0,
                         1,
                        color: '#808080'
                    }]
                },
                tooltip: {
                    formatter: function () {
                        return '<b>' + this.series.name + '</b><br/>' +
                            Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
                            Highcharts.numberFormat(this.y, 2);
                    }
                },
                legend: {
                    enabled: false
                },
                exporting: {
                    enabled: false
                },
                series: [{
                    name: 'Random data',
                    data: (function () {
                        // generate an array of random data
                        var data = [],
                            time = (new Date()).getTime(),
                            i;
    
                        for (i = -19; i <= 0; i += 1) {
                            data.push({
                                x: time + i * 1000,
                                y: Math.random()
                            });
                        }
                        return data;
                    }())
                }]
            });
        });
    });
    		</script>
    	</head>
    	<body>
    <script src="js/highcharts.js"></script>
    <script src="js/modules/exporting.js"></script>
    
    <div id="container" style="min- 310px; height: 400px; margin: 0 auto"></div>
    
    	</body>
    </html>
    



          

  • 相关阅读:
    const
    ImportError: No module named google.protobuf
    ImportError: No module named google.protobuf
    多线程同步与单线程异步对比
    多线程同步与单线程异步对比
    再谈select, iocp, epoll,kqueue及各种I/O复用机制
    再谈select, iocp, epoll,kqueue及各种I/O复用机制
    poj1180
    poj3254
    poj3321
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5043582.html
Copyright © 2011-2022 走看看