负载均衡 ip_hash

  • ip_hash 可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
  • 使用ip_hash的注意点:
    不能把后台服务器直接移除,只能标记 down .

If one of the servers needs to be temporarily removed, it should be marked with the down parameter in order to preserve the current hashing of client IP addresses

upstream tomcats { 
	ip_hash; 
	server 192.168.11.73:8080; 
	server 192.168.11.74:8080 down; 
	server 192.168.11.75:8080; 
}

参考:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash

hash算法带来的问题

在这里插入图片描述
ip hash的话,它其实是有普通的哈希算法,它会有一个问题,在集群中都会出现。

假定我们现在的用户呢,他的IP是固定的,没有发生更改,这些用户有5678,他们都分别访问到我们特定的服务器了。

现在我们tomcat3也就是下标为2的这台服务器发生了问题,它宕机了,可能就没有了,这个时候我们的节点发生了更改,由3变为了2。

这个时候我们之前的这些所有的求模其实都应该要重新去计算了吧,原来是5模3,这个时候它就会变成5模2。它发生了更改,它取得的一个数值是1,所以这个时候这个5的话,它就会访问到图案tomcat2,它的下标为1了。

如果说是在真实环境中出现了这种问题的话,我们其实是在这里的前端用户,他的请求量是会有很多的。所有的一些请求都要重新的去进行计算他的一个后台服务器的一个集群可能不是三台,他有可能是几十台。发生这种更改的话,他都会去进行一个重新的全模运算。

当然我们现在是减少的一种情况,如果说我们的节点增加,节点增加的话,它其实也会发生这种问题。
不管是我们的服务器节点是增加还是减少,它的这个算法其实都会去进行一次重新的计算的,重新计算所带来的一个结果就是用户在原来的服务系统里面的会话都会丢失,并且我们在服务器里面所设置的一些相应的缓存,也会请求不到。

这样子的话就会造成用户在请求的时候,他的时间就会请求的会更大,比原先更多。

那么如何去解决普通的哈希算法呢?其实还会有一种新的算法,这个叫做一致性哈希算法,我们可以先来看一下。
在这里插入图片描述

首先我们呢有一条水平线或者说是一条直线,在一条直线的开头和结尾,我们分别定义为0和2的32次方减1。
在这里插入图片描述

这个的话其实就相当于是一个地址,或者说你可以把它们当做是一个门牌号。

对于这样的一条直线的话,就是我们可以把它给弯过来吧,弯过来了以后,其实它就组装成了一个环形,它是一个圆形的。这样子它从0到2的32次方减1。

这个时候其实从零到这个位置,其实就形成了一个闭环,随后呢我们就可以来根据我们的一个哈希算法去算了,如何去算呢?

假设我们现在有一些服务器,有第一台服务器,这台服务器经过哈希算法,这个时候它的一个节点1这个其实是我们服务器的一个IP,或者说是我们服务器的一个主机名,所有的哈希都是根据这样的一个规则去算的。

算好了以后,其实我们就可以把这一台服务器放到了我们这个环境里面去,就相当于是一个地址。

假设我们是把这个经过哈希值以后放到了这个位置,这个其实就是在0到2的32方减1,这里面的某一个特定的位置,它是固定在这个环上的。

这个计算机节点经过哈希制以后,它也是会固定在这个环上的某一个位置,随后同理,我们所有的节点,它会按照这个环的顺时针动向一个一个去放。现在其实我们总共是放了四个计算机节点,总共是有4台服务器,它都会有一个特定的位置的。

有了特定的位置以后,其实一定要注意,他们都是经过了哈希算法的,每一个哈希的算法要么是根据服务器的一个IP,要么是根据服务器的一个主机名,两者都可以,并且他们都是一个顺时针的方向。

随后这个时候会有一些用户,用户的话也是可以根据他的ID去算的,这个时候得到他的一个哈希值了以后,这个用户的话他也会存在于我们这一个环上的某一个地址。

假定这两个用户是存在在这个部位,由于我们的有一个规则,就是说每一个用户离着我们的某一个节点近的话,这个用户就去访问某一个节点,并且它是按照顺时针的方向。

现在我们这两个用户是在这个位置的,在这个位置的话,由于是顺时针,所以他们都会访问到节点1。现在我们又有两个用户进来,这两个用户的请求,他们经过哈希算法以后,是在这个位置,在这个位置了以后,按照我们的一个顺时针的方向。

这两个其实就应该访问到我们的节点2了吧。同理在后方我们出现的一个用户的话,这两个用户由于是顺时针就应该要访问到我们的节点3了之后,在这个位置又出现了一个用户的请求。

这个就是一次性哈希的算法。

它可以保证我们的用户可以访问到我们特定的一个服务器节点,并且他们相当于是一种就近原则。

然后我们再来看一下服务器减少的情况,服务器减少的话就相当于是服务器宕机,挂掉了,我们要去移除。

在这里插入图片描述

移除了以后你会发现这边多了两个用户,这两个用户现在他本来是访问节点3的,这个时候怎么办呢?

我们可以把这两个用户直接把他们的请求是放到了节点4,也就是这两个用户原来的会话,或者说原来请求的些缓存全部都丢失了,他们会访问到我们的节点4。

但是我们在此之前,其余的用户除了这两个用户以外的其他所有的用户,他们的一个访问没有变化,还是照旧,他们的会话,他们的缓存等等信息,其实全部都会保留在他原来的一些服务器节点里面是不会被丢失的。

这个其实就是一致性哈希算法。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐