一致性hash

什么是一致性hash

常见的负载均衡转发算法有几种,例如随机、轮询、hash等。hash主要是可以一定程度的保证同一类请求每次都可以路由到同一个下游实例进行处理。
常见的hash方法就是取余。假设下游实例有4台,那么每个请求,把请求转化成一个整形,然后%4算出来一个下游实例的下标。这种方法实现简单,但是仔细想下,如果下游增加一个实例,或者去掉一个实例,则整个映射关系都变了。原本去实例1的会去到实例2,这样横向的扩展能力比较差,每次实例数变更都是灾难。
对此,一致性hash出来了。
如下图,一致性hash,就是把整个hash值当成环,比如说我们把 2^32当成一个环,先把实例的一个标识换算成uint32,然后插入到环上,如下图的ip1、ip2、ip3、ip4。当过来一个user1请求,转化成uint32,再从环中按顺时针找到一个实例,根据下图找到ip2实例进行处理。
在这里插入图片描述

一致性hash的意义

一致性hash最主要的优点是可扩展性好。当我们增加一个实例5时,如下图的ip5,算出来是在ip4到ip1之间,则条件完后影响的请求数只是ip4到ip5中的这部分请求,原本是去到ip1实例,改成去到ip5。
总的来说就是下游实例新增或减少,可以较少影响请求到实例的映射关系。
在这里插入图片描述

一致性hash的优化

如上图,一致性hash其实相对于取余的方式,比较明显的缺点就是各个实例分配到的请求数会不均匀,如上面ip5和ip1,所处理的请求明显不是不对等。
对于不均匀这种问题,一般会采用虚拟节点的方式来解决。虚拟节点,大致就是每个实例,我们不只算出一个uInt32 hash值。比如我们原本是ip地址"192.168.1.1"算出一个值,则现在我们按照"192.168.1.1#1"、“192.168.1.2#2”,以此类推算出20个虚拟节点,插入到hash环中,这样落到该虚拟节点的请求,实际上也是落到由该ip实例进行处理。想要hash环相对均匀,主要看生成虚拟节点的算法。
总的来说,虚拟节点还是可以比较大程度的环境不均匀的问题。

一致性hash的实现

这里给出个人认为可行的一致性hash的c++的实现方式。
字符串转化uint32,可以用crc或者md5,取出所要的字节。或者md5每4个字节做相加之类的。
存储的数据结构采用std::map<uint32_t, node*>,node为实例结构体,每个虚拟节点都指向同个node。每添加一个node,都算多20个虚拟节点。
利用std::map的upper_bound函数,取出最接近它的实例,然后进行转发。后面有时间会补上代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值