引言
负载均衡是什么呢,我们首先来看看wiki对这个名词的解释:
负载均衡(Load balancing)是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡服务通常是由专用软件和硬件来完成。 主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发和高可用的问题。
是的,我们可以清楚的看到负载均衡是一种将请求均匀的分摊到多台服务器上的技术,当我们使用一个合理的负载均衡算法时,理论上整个集群的负载能力是线性提升的.当然这个的概念也可扩展至单机多CPU.一般来说负载均衡分为以下两种:
- 一种是
请求负载均衡
,即将用户的请求均衡地分发到不同的服务器进行处理. - 另一种是
数据负载均衡
,即将用户更新的数据分发到不同的存储服务器.
其实负载均衡这个概念还是非常普遍的,从网络层的角度来看,有基于DNS,IP,HTTP等协议的负载均衡算法,其实这些也属于基于请求.而在应用层,也有相应的负载均衡算法,如下:
基于请求的负载均衡
- 简单轮询
- 加权轮询
- 加权轮询改进(Nginx)
- 随机策略
基于数据的负载均衡
- 一致性哈希(以及一些改进,比如虚拟节点,有限负载)
- 哈希槽
- 基于关键字
我们可以看到其实在基于数据的负载均衡中所展现的算法其实就是数据分片中使用的算法,因为数据分片也要求数据的负载均衡,也就是我们所说的基于数据的负载均衡.
至于基于请求和基于数据的负载均衡其中具体细节我们就不再说了,其他博客说的很清楚,那么如何在我们的项目中选择这些算法呢?其实主要基于如下几个条件:
服务器节点的异构性
(即各个服务器节点的处理能力).也就是我们每一个服务器的资源是不同的(可以是算力,可以是存储能力),显然一般的简单轮询无法做到对于拥有不同异构性服务器节点的负载均衡,而加权轮询则可很好的解决这个问题.就这样也可以看出简单轮询其实是适合每个请求的请求资源是相近的.服务器处理请求的开销
.我们每一个请求的开销是不同的,如何根据不同的请求选择合适的服务器呢?有两种方法,一种是使用单体调度的思路,即每个从节点会向主节点汇报自己的空闲资源,当请求到来时,主节点通过资源调度算法选择一个合适的从节点来处理该请求;第二种是是使用一致性哈希,从哈希函数上入手,让请求所需的资源和服务器节点的空闲资源与哈希函数挂钩,即通过将资源作为自变量带入哈希函数进行计算,从而映射到哈希环中.当然这一切都需要我们能够计算资源.请求是否有状态
(处理请求的过程是否完全依赖于请求).这其实就是每个请求之间是否有因果关系,典型的就是HTTP的短连接,显然每一个请求只依赖于自己请求的url或者额外数据而与其他http请求无关,这就是典型的无状态请求.这也意味同一个请求可以分布到不同的节点上,这就意味着其适合于轮询,随机这类算法.当遇到有状态的请求时,显然我们需要多个请求落在同一个节点上或者全部节点收敛于一致状态来保证数据一致性.此时我们就可以使用哈希相关的负载均衡算法,当然也有类似于cookie这样的解决方式.
总结
以上三点其实是我真正想说的点,根据不同的业务需求我们需要去选择不同的负载均衡算法,耳熟能详的:Nginx使用了轮询算法,Dubbo使用了随机算法,Redis使用了哈希槽,Memcache使用了一致性哈希(带虚拟节点).
参考:
有状态和无状态