• 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值落在的服务器节点。

  • 相关阅读:
    移动端HTML5音频与视频问题及解决方案
    git did not exit cleanly
    移动端事件对象touches的误区
    原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
    H5+JS+CSS3 综合应用
    深入理解CSS3 Animation 帧动画
    在 MacOS 中使用 multipass 安装 microk8s 环境
    [译] Design patterns for container-based distributed systems
    Sangmado 公共基础类库
    Redola.Rpc 集成 Consul 服务发现
  • 原文地址:https://www.cnblogs.com/cnsec/p/13407027.html
Copyright © 2020-2023  润新知