crc32算法_一致性hash算法负载均衡

bf0fe2692c5ed83a0a7d8d977210943c.png

有没有好奇过redis、memcache等是怎么实现集群负载均衡的呢?

其实他们都是通过一致性hash算法实现节点调度的。

讲一致性hash算法前,先简述一下求余hash算法:

hash(object)%N
  • 一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) ;

  • 由于QPS升高,我们需要添加多一台服务器,这时候服务器是 N+1 台,映射公式变成了 hash(object)%(N+1) 。

1 和 2 的改变都会出现所有服务器需要进行数据迁移。

一致性HASH算法

一致性HASH算法的出现有效的解决了上面普通求余算法在节点变动后面临全部缓存失效的问题:

type Consistent struct {numOfVirtualNode inthashSortedNodes []uint32circle map[uint32]stringnodes map[string]bool}

简单地说,一致性哈希将整个哈希值空间组织成一个虚拟的圆环,如假设某空间哈希函数H的值空间是0-2^32-1(即哈希值是一个32位无符号整形),整个哈希空间如下:

753ed011a91fe2f71de8b4a8770bd5df.png

下一步将各个服务器使用哈希算法计算出每台机器的位置,具体可以使用服务器的IP地址或者主机名作为关键字,并且是按照顺时针排列:

//这里我选择crc32,具体情况具体安排func hashKey(host string) uint32 { scratch := []byte(host)return crc32.ChecksumIEEE(scratch)}

这里我们假设三台节点memcache经计算后位置如下:

3441c665e536ccf22e2a4b3141aca936.png

//add the nodec.Add("Memcache_server01")c.Add("Memcache_server02")c.Add("Memcache_server03")func (c *Consistent) Add(node string) error {if _, ok := c.nodes[node]; ok {return errors.New("host already existed")}c.nodes[node] = true// add virtual nodefor i := 0; i < c.numOfVirtualNode; i++ {virtualKey := getVirtualKey(i, node)c.circle[virtualKey] = nodec.hashSortedNodes = append(c.hashSortedNodes, virtualKey)}sort.Slice(c.hashSortedNodes, func(i, j int) bool {return c.hashSortedNodes[i] < c.hashSortedNodes[j]})return nil}

接下来使用相同算法计算出数据的哈希值,并由此确定数据在此哈希环上的位置

假如我们有数据A、B、C和D,经过哈希计算后位置如下:

96ed9c621091d90e92875864738b6885.png

根据一致性哈希算法,数据A就被绑定到了server01上,D被绑定到了server02上,B、C在server03上,是按照顺时针找最近服务节点方法

这样得到的哈希环调度方法,有很高的容错性和可扩展性:

假设server03宕机

93b2e6aafa38d0ff74987ec795fbeb43.png

可以看到此时A、C、B不会受到影响,只是将B、C节点被重定位到Server 1。一般的,在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

考虑另外一种情况,如果我们在系统中增加一台服务器Memcached Server 04:

692ec9954027e02cc7f75643b9ef833a.png

此时A、D、C不受影响,只有B需要重定位到新的Server 4。一般的,在一致性哈希算法中,如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

来源: https://www.cnblogs.com/starluke/p/11997694.html

·END·

PHP开源社区进阶·提升·涨薪af87f84e7c42d8d578aea30a0b16fe97.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值