一个简单的一致性哈希的负载均衡,附带代码

        基于一致性哈希实现的负载均衡。一致性哈希主要需要注意以下几点:

一,根据用户IP或者ID等大体固定的数据进行hash求值,以保证每次相同的用户尽量可以hash到固定的服务器上去。

二,为了保证每台服务器的效能能够充分利用,例如有的服务器性能较好,性能为3,有的服务器性能一般,性能为2。不同的服务器可以对其不同的虚拟节点,以保证效能的充分利用。

三,考虑雪崩现象,一般hash也可以达到前两点,但是如果一台服务器崩溃,那么所有的用户请求压到下一台服务器,很可能该服务器也崩溃,以此类推,造成雪崩现象。

四,属于优化点,当服务器正常运行,此时新加一台服务器,应当适量的为该服务器增加以下映射量。

        大体思路:使用数组模拟虚拟节点,不同的服务器为其传递不同的权值,根据权值映射到该虚拟数组中。例如,开辟一百个大小的数组,初始值均为零,新加一台权值为4的服务器,那么进行hash四次,映射到的位置保存该服务器的编号值。当客户端的连接来到的时候,根据固定值进行hash求值,得到对应的服务器编号,从map表中找到对应的服务器,转发该消息。

        特殊情况:减少服务器时,该服务器在虚拟数组上的hash位置的值存储为其上一个点或者下一个点(有效点,即值非0的点)的值。本代码存储上一个有效点。

        极端情况:如果需要频繁的增加和删除。注意,这里是和,不是或。那么可能会造成虚拟节点趋近于相同化,即某个固定值极对应的位置极可能很相近。

先附上代码,再附上找负载均衡时候总结的资料。

<balance.h>

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
#include <set>


class server
{
public:
	server(int socket, int weight) :_socket(socket),_num(0),_online_num(0),_weight(weight){}
	int get_socket(){ return _socket; }
	int OnlineNum() { return _online_num; }
	void addClient(){ _online_num++; }
	void delClient(){ _online_num--; }
	int get_ServerNum(){ return _num; } //该编号就是balance类中的键值
	void set_ServerNum(int num){ _num = num; }
	int get_Weight(){ return _weight; }
	void sendMsg(std::string &strMsg);
	void recvMsg(std::string &strMsg){ _strMsg = strMsg; }
	//~server(){ close _socket; }
private:
	int _socket;
	int _online_num; //在线人数
	int _num; //编号
	int _weight; //权值
	std::string _strMsg; //Msg消息
};
class client
{
public:
	client(int socket, int id) :_socket(socket),_id(id){}
	void set_num(int iNum){ _num = iNum; }
	int get_num(){ return _num; }
	int getId(){ return _id; }
	void sendMsg(std::string &strMsg); //s->c
	void recvMsg(std::string &strMsg){ _strMsg = strMsg; }
	//~client(){ close(_socket); }
private:
	int _socket;
	int _num; //虚拟数组编号
	int _id; //id
	std::string _strMsg; //消息字符串
};
class balance
{
public:
	static balance *getInstance(int iSize){
		if (instance == NULL){
			instance = new balance(iSize);
		}
		return instance;
	}
	void addOnlineNum(){ _online_num++; }
	void delOnlineNum(){ _online_num--; }
	void delOnlineNum(int iNum){ _online_num -= iNum; }
	int getOnlineNum(){ return _online_num; }
	bool addServer(server *ser);
	bool delServer(server *ser);
	int allWriteNum();
	//映射节点
	void addVirualPoint(server *ser);
	//去掉映射节点
	void delVirualPoint(server *ser);
	//获取一个map中的空位置 error:-1
	int getSpacePos();
	//随机一个数组的位置
	int getVirualVecPos();

	//一个新连接
	void addClient(client *cli)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值