负载均衡算法--源地址哈希法(Hash)

Posted 志波同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了负载均衡算法--源地址哈希法(Hash)相关的知识,希望对你有一定的参考价值。

接上一篇博文:负载均衡算法–平滑加权轮询法(Smooth Weight Round Robin)。接下来介绍源地址哈希法。

源地址哈希法是根据请求来源的地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一源地址的请求,当服务器列表不变时,它每次都会映射到同一台服务器进行访问。

算法描述

假设有 N 台服务器 S = S0, S1, S2, …, Sn-1,算法可以描述为:
1、通过指定的哈希函数,计算请求来源的地址的哈希值
2、对哈希值进行求余,底数为 N
3、将余数作为索引值,从 S 中获取对应的服务器;

假定我们现在有如下四台服务器:

服务器地址权重
192.168.1.11
192.168.1.22
192.168.1.33
192.168.1.44

源地址哈希法与权重没有关系,只与源地址有关。

代码实现

1、服务器管理类

package org.learn.loadbalance;

import java.util.Map;
import java.util.TreeMap;

/**
 * @author zhibo
 * @date 2019/5/16 16:25
 */
public class ServerManager 
    public volatile static Map<String, Integer> serverMap = new TreeMap<>();

    static 
        serverMap.put("192.168.1.1", 1);
        serverMap.put("192.168.1.2", 2);
        serverMap.put("192.168.1.3", 3);
        serverMap.put("192.168.1.4", 4);
    


2、源地址哈希类

package org.learn.loadbalance;

import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhibo
 * @date 2019/5/16 16:28
 */
public class HashBalance 

    public static String getServer(String sourceIp) 
        if(sourceIp == null)
            return "";
        
        Set<String> serverSet = ServerManager.serverMap.keySet();
        ArrayList<String> serverList = new ArrayList<>(serverSet);

        Integer index = sourceIp.hashCode() % serverList.size();
        return serverList.get(index);
    

    public static void main(String[] args) 
        for (int i = 0; i < 10; i++) 
            String server = getServer("ip" + new Random().nextInt(1000));
            System.out.println(server);
        
    


执行 main 方法输出结果如下:

优点:
源地址哈希法可以保证,只要请求源地址不变,总会请求到相同的目标服务器。在早些时候进行 Web 开发时,是基于 Session 进行用户鉴权的,用户登录后,会在登录时的服务器A的 Session 中设置用户信息,如果下一次请求被分配到服务器B上,那么此时因 Session 中没有用户信息而报错。在这种场景下一般会使用源地址哈希法进行负载均衡,保证用户每次都可以访问到 Session 信息。当然现在的一般不会使用 Session 进行鉴权了,大都采用 redis、memcached 等缓存服务来解决 Session 不共享的问题。

缺点:
源地址哈希法可以保证,只要请求源地址不变,总会请求到相同的目标服务器。这样会带来两个问题:
1、由于用户的活跃度不同,可能会有大量的活跃用户被哈希到相同的服务器上,造成该服务器特别繁忙,大量的非活跃用户被哈希到相同的服务器上,造成该服务器几乎没有请求,造成请求不均衡。
2、一旦某个服务器挂掉,那么哈希到该服务器的所有源请求都会失败,直到服务恢复或者服务器列表中去掉该服务器。

文章内容仅代表个人观点,如有不正之处,欢迎批评指正,谢谢大家。

以上是关于负载均衡算法--源地址哈希法(Hash)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构和算法 负载均衡算法

浅析负载均衡的6种算法,Ngnix的5种算法。

使用Nginx实现负载均衡

Nginx负载均衡中常见的算法及原理

负载均衡|六种负载均衡算法

负载均衡算法