zoukankan      html  css  js  c++  java
  • 一致性哈希虚节点解决雪崩问题

    一致性哈希的基本原理大家都知道,就是找一个最近的节点或者顺时针,逆时针找一个节点,而不是通过模一个N去找节点,这样做的好处就是当其中一台磬机的时候,一致性哈希还可以继续工作,而模N的方法,所有定位在磬机节点上都会失败。如下代码是一个简单的一致性哈希:

    <?php
    class Redis {
        
        //redis实例的id
        public $id;
    
        public function __construct($id) {
            $this->id = $id;
        }
    
        public function set($key, $value) {
            echo 'redis '.$this->id.': set key '. $key.'</br>';
        }
    
        public function ok() {
            return true;
        }
    }
    
    class RedisGlobal {
    
        public $redis = array();
    
        public function addServer($redis) {
            $this->redis[md5($redis->id)] = $redis;
        }
    
        public function set($key, $value) {
            $hash = md5($key);
            $serverFind = $hash;
            ksort($this->redis, SORT_REGULAR);
            foreach ($this->redis as $serverIndex=>$redis) {
                if ($serverIndex > $serverFind) {
                    //找到一个server节点,检测该节点上redis是否可用
                    if ($redis->ok()) {
                        $redis->set($key, $value);
                        break;
                    }
                }
            }
        }
    
    }
    
    $global = new RedisGlobal();
    $global->addServer(new Redis(1));
    $global->addServer(new Redis(2));
    $global->addServer(new Redis(3));
    for ($i=0; $i<10; $i++) {
        $global->set($i, $i);
    }
    ?>

    //output
    redis 3: set key 0
    redis 2: set key 1
    redis 3: set key 2
    redis 1: set key 4
    redis 3: set key 5
    redis 1: set key 6
    redis 1: set key 7
    redis 3: set key 8
    redis 1: set key 9

    以上代码基本OK,不过上面的代码主要有三个问题,也是一致性哈希基本思想存在的问题。面试中也经常考察一个方案的弊端。

    1.分布不均匀。

    2.当一台磬机以后,磬机节点的所有请求会落到下一台主机,这样就有可能使下一台主机也磬机,这就是雪崩问题。

    3.不同主机处理能力不同如何配置量。

    解决以上两个问题,是通过配虚节点,也就是一个主机映射N个节点,下面的例子中默认映射100个节点,处理能力较强的主机可以配200或者更高的虚节点数量。

    <?php
    class Redis {
        
        //redis实例的id
        public $id;
    
        public function __construct($id) {
            $this->id = $id;
        }
    
        public function set($key, $value) {
            echo 'redis '.$this->id.': set key '. $key.'</br>';
        }
    
        public function ok() {
            return true;
        }
    }
    
    class RedisGlobal {
    
        public $redis = array();
    
        public function addServer($redis, $weight=100) {
            for ($i=0; $i<$weight; $i++) {
                $this->redis[md5($redis->id.'-'.$i)] = $redis;
            }
        }
    
        public function set($key, $value) {
            $hash = md5($key);
            $serverFind = $hash;
            ksort($this->redis, SORT_REGULAR);
            foreach ($this->redis as $serverIndex=>$redis) {
                if ($serverIndex > $serverFind) {
                    //找到一个server节点,检测该节点上redis是否可用
                    if ($redis->ok()) {
                        $redis->set($key, $value);
                        break;
                    }
                }
            }
        }
    
    }
    
    $global = new RedisGlobal();
    $global->addServer(new Redis(1));
    $global->addServer(new Redis(2));
    $global->addServer(new Redis(3));
    for ($i=0; $i<10; $i++) {
        $global->set($i, $i);
    }
    ?>

    //output
    redis 1: set key 0
    redis 1: set key 1
    redis 3: set key 2
    redis 1: set key 3
    redis 2: set key 4
    redis 1: set key 5
    redis 2: set key 6
    redis 2: set key 7
    redis 3: set key 8
    redis 1: set key 9
  • 相关阅读:
    element input搜索框探索
    Github网站css加载不出来的处理方法(转,亲测有效)
    通过用axios发送请求,全局拦截请求,获取到错误弄明白promise对象
    vuex和localStorage/sessionStorage 区别
    leetcode刷题笔记十一 盛最多水的容器 Scala版本
    leetcode刷题笔记十 正则表达式 Scala版本
    leetcode刷题笔记九 回文数 Scala版本
    leetcode刷题笔记八 字符串转整性 Scala版本
    leetcode刷题笔记七 整数反转 Scala版本
    leetcode刷题笔记六 Z字型转换 Scala版本
  • 原文地址:https://www.cnblogs.com/23lalala/p/3588553.html
Copyright © 2011-2022 走看看