欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

负载均衡算法

程序员文章站 2024-03-16 14:18:22
...

分布式算法-一致性哈希:

一个分布式系统,需要将数据存储到具体的节点上,如果用普通哈希取模进行,如果增加服务器或者服务器宕机,同一个KEY经过哈希后再对总数取模结果就和原来不同,会导致数据丢失。
所以引入一致性哈希:
先用hash函数映射到一个圆环上:
负载均衡算法

需要服务器时,先根据hash算法算出KEY的hash值,对应到这个环中的位置:如上图中的K1,顺时针找到服务器B,K1存入B中,B如果宕机了B上的数据就会落到C节点上:
负载均衡算法

这样就只会影响C节点,对其他服务器不会影响,但是可能造成C节点负担过重导致宕机。
所以又引入“虚拟节点”:
想象环上有很多虚拟节点,一个真实的服务器对应多个节点,顺时针寻找虚拟节点,就找到对应的真实服务器节点
负载均衡算法

图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象。

hash函数MD5加密的,但是复杂度高,有损耗;
MurMurHash非加密算法,但是快,而且碰撞率低;

#include <map>
using namespace std;

class ConsistentHash
{
public:
    ConsistentHash(int node_num, int virtual_node_num);
    ~ConsistentHash();

    void Initialize();
    size_t GetServerIndex(const char* key);

    void DeleteNode(const int index);
    void AddNewNode(const int index);

private:
    map<uint32_t,size_t> server_nodes_; //虚拟节点,key是哈希值,value是机器的index
    int node_num_;//真实机器节点个数
    int virtual_node_num_;//每个机器节点关联的虚拟节点个数
};


#include <map>
#include <string.h>
#include <sstream>
#include "consistent_hash.h"
#include "murmurhash3.h"
using namespace std;

ConsistentHash::ConsistentHash(int node_num, int virtual_node_num)
{
    node_num_ = node_num;
    virtual_node_num_ = virtual_node_num;
}

ConsistentHash::~ConsistentHash()
{
    server_nodes_.clear();
}


void ConsistentHash::Initialize()
{
    for(int i=0; i<node_num_; ++i)
    {
        for(int j=0; j<virtual_node_num_; ++j)
        {
            stringstream node_key;
            node_key<<"SHARD-"<<i<<"-NODE-"<<j;
            uint32_t partition = murmur3_32(node_key.str().c_str(), strlen(node_key.str().c_str()));
            server_nodes_.insert(pair<uint32_t, size_t>(partition, i));
        }
    }
}


size_t ConsistentHash::GetServerIndex(const char* key)
{
    uint32_t partition = murmur3_32(key, strlen(key));
    map<uint32_t, size_t>::iterator it = server_nodes_.lower_bound(partition);//沿环的顺时针找到一个大于等于key的虚拟节点

    if(it == server_nodes_.end())//未找到
    {
        return server_nodes_.begin()->second;
    }
    return it->second;
}


void ConsistentHash::DeleteNode(const int index)
{
    for(int j=0; j<virtual_node_num_; ++j)
    {
        stringstream node_key;
        node_key<<"SHARD-"<<index<<"-NODE-"<<j;
        uint32_t partition = murmur3_32(node_key.str().c_str(), strlen(node_key.str().c_str()));
        map<uint32_t,size_t>::iterator it = server_nodes_.find(partition);
        if(it != server_nodes_.end())
        {
            server_nodes_.erase(it);
        }
    }
}

void ConsistentHash::AddNewNode(const int index)
{
    for(int j=0; j<virtual_node_num_; ++j)
    {
        stringstream node_key;
        node_key<<"SHARD-"<<index<<"-NODE-"<<j;
        uint32_t partition = murmur3_32(node_key.str().c_str(), strlen(node_key.str().c_str()));
        server_nodes_.insert(pair<uint32_t, size_t>(partition, index));
    }
}

一致性哈希特点:
平衡性(Balance)
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
降低分散性