memcache分布式集群算法——求模算法
memcached是一个分布式缓存,允许配置多个节点,但是memcached在这多个节点之间不能实现自动分配数据,换句话说,memcached节点之间,是不互相通信的。因此,memcached的分布式,是需要用户的算法来设计的,将数据分布在不同的节点中。
求模算法
假设有n个节点,从0~n-1编号,key对n求模,余i,则key落在第i台服务器上。
但是存在一个命中率的问题:
假设这5台服务器突然挂了一台,那么求模的底数则由5变为4。就会有
key0%5 = 0,key0%4 = 0 hit
key1%5 = 1,key1%4 = 1 hit
key2%5 = 2,key2%4 = 2 hit
key3%5 = 3,key3%4 = 3 hit
key4%5 = 4,key4%4 = 0 miss
......
key19%5 = 4 ,key19%4=3 miss
归纳:
有n台服务器,变为n-1台服务器
每 n*(n-1)个数据中, 只有(n-1)个单元对n和(n-1)求模得到相同的结果、
所以 命中率在服务器 down 的短期内, 急剧下降至 (n-1)/(n*(n-1)) = 1/(n-1)
所以: 服务器越多, 则 down 机的后果越严重
求模算法代码
<?php
//hash接口
interface hash{
public function _hash($key);
}
//分布式搜索策略
interface distribution{
public function looup($key);
}
/**
* 求模算法
*/
class Moder implements hash,distribution{
public $nodes = [];//服务器节点
//重写hash接口中的_hash方法
public function _hash($key){
return sprintf("%u",crc32($key));
}
//重写分布式接口中的looup方法
public function looup($key){
$hashKey = $this->_hash($key);
$num = count($this->nodes);
$mod = fmod($hashKey, $num);
return $this->nodes[$mod];
}
//添加服务器节点方法
public function addNode($node){
if(in_array($node, $this->nodes)){
return;
}
$this->nodes[] = $node;
}
//删除一台节点,模拟down机
public function delNode($node){
foreach ($this->nodes as $k => $n) {
if($node == $n){
unset($this->nodes[$k]);
}
}
array_values($this->nodes);//重新编排键
}
}
$con = new Moder();
$con->addNode('a');
$con->addNode('b');
$con->addNode('c');
$con->addNode('d');
echo $con->_hash('title');echo $con->looup('title');echo "<br/>";
echo $con->_hash('name');echo $con->looup('name');echo "<br/>";
echo $con->_hash('age');echo $con->looup('age');echo "<br/>";
首先需要创建一个Moder类的实例,然后添加服务器节点,调用addNode方法,在addNode中首先判断服务器是否已经存在该节点,如果不存在,就添加服务器上。
如果需要查找某个数据,可以调用looup方法,这个方法首先将key转换成hash值,然后将这个hash值和服务器的节点数量求模,然后根据余数返回该key值落在的服务器节点。
网络上志同道合,我们一起学习网络安全,一起进步,QQ群:694839022