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的压力。
以下是我的一段代码:
_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的代码:
$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 的命中率:
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 命中率
Highcharts Example