服务器集群负载均衡原理?

服务器集群负载均衡原理?

负载均衡有硬件和软件两种.

硬件层的比较牛逼,将4-7层负载均衡功能做到一个硬件里面,如F5,梭子鱼,据说yahoo中国!早些时候只用了两台F5做双活.

目前主流的软件负载均衡分为四层和七层

LVS属于四层负载均衡,工作在tcp/ip协议栈上,通过修改网络包的ip地址和端口来转发, 由于效率比七层高,一般放在架构的前端.

七层的负载均衡有nginx, haproxy, apache等, 工作在应用层,因此可以将HTTP请求等应用数据发送到具体的应用服务器,如将图片请求转发到特定的服务器上,总之可以做到更智能的负载均衡,这些功能在四层负载均衡上不好实现,一般放在架构的后面位置,布置在应用服务器前面.

建议查看:

《构建高性能Web站点》第12章 web负载均衡

《大型网站技术架构:核心原理与案例分析》 6.2 应用服务器集群的伸缩性设计

写的比较详细~

下面的内容摘录自以上两书:

12.2 HTTP重定向

Web服务器可通过Http响应头信息中的Location标记来返回一个新的URL,浏览器自动去访问这个新的URL。

实现:可以通过Web应用程序代码实现你想到的调度策略,如可根据请求的URL的不同来进行合理的过滤和转移。

12.3 DNS负载均衡

DNS负责将用户请求的域名映射为实际的IP地址,这种映射可以是一对多的( DNS的A记录,用来指定域名对应的IP地址),这样DNS服务器便充当负载均衡调度器。

DNS节省了所谓的主站点,DNS服务器已经充当了主站点的职能。常见的策略是对多个A记录进行RR(轮询)

12.4 反向代理负载均衡

反向代理服务器的核心工作是转发 HTTP ,它工作在HTTP层面,因此,基于反向代理的负载均衡也称为七层负载均衡。

任何对于实际服务器的HTTP请求都必须经过调度器;调度器必须等待实际服务器的HTTP响应,并将它反馈给用户。

12.5 IP负载均衡

网络地址转换(NAT)负载均衡工作在传输层,对数据包中的IP地址和端口进行修改,从而达到转发的目的,称为四层负载均衡。

NAT服务器(前端服务器)必须作为实际服务器(后端服务器)的网关,否则数据包被转发后将一去不返。

12.6 直接路由

这种方式工作在数据链路层。它修改数据包的目标MAC地址,并没有修改目标IP(因为这种转发工作在数据链路层,它对上层端口无能为力),然后发给实际的服务器,实际服务器的响应数据直接发回给用户,而不用经过调度器。但实际服务器必须接入外网,而且不能将调度器作为默认网关,要给实际服务器添加和调度器IP地址相同的IP别名。

12.7 IP隧道

基于IP隧道的负载均衡系统也可以使用LVS来实现,称为 LVS-TUN 。与LVS-DR不同的是,实际服务器和调度器可以不在同一个WAN网段,调度器通过IP隧道技术来转发请求到实际服务器,所以实际服务器必须有合法的IP地址。

基于IP隧道的请求转发机制,是将调度器收到的IP数据包封装在一个新的IP数据包中,转交给实际服务器,然后实际服务器的响应数据包可以直接到达用户端。

基于IP隧道的独特方式,可以将实际服务器部署在不同的地域并根据就近原则转移请求,比如一些CDN服务器就是基于IP隧道技术实现的。

负载均衡,核心就是网络流量分发,分很多维度。

从网络层看,基本是四层(TCP,UDP),和七层(HTTP,HTTPS等),基本就是解析到对应的网络层,然后根据不同特征分发。比如四层的,基本就是根据连接信息(TCP)或者本身的特征(源IP,目标IP)等做。七层的,就可以用域名(HTTP头里的Host),URL,Cookie,Header这些来做。

从实现上看,基本可以分软负载均衡和反向代理:

从实现方式看,有软件负载均衡和硬件负载均衡:

每个云服务都会提供负载均衡服务( 负载均衡服务_流量分发服务-网易云 ),拿来直接用就好啦,省时又省力,可以将更多精力放在核心业务上面。

相关阅读: 3分钟带你了解负载均衡服务

简单说有global server load balance和local server load balance;global slb一般是跨机房跨区域的,主要在查询DNS的时候根据就近原则返回距离client最近的机房的ip;local slb一般是部署在同一个机房或者区域内进行,可以通过修改IP,port,http header or body等方式来把流量分给多个server。

有两本书可以参考:

关于SLB理论的《Load Balancing Servers, Firewalls, and Caches》

还有F5的BigIP实作的:《应用交付之F5 BIG-IP LTM》

当系统面临大量用户访问,负载过高的时候,通常会使用增加服务器数量来进行横向扩展,使用集群和负载均衡提高整个系统的处理能力。

而我们讨论的负载均衡一般分为两种,一种是基于DNS,另一种基于IP报文。

利用DNS实现负载均衡,就是在DNS服务器配置多个A记录,不同的DNS请求会解析到不同的IP地址。大型网站一般使用DNS作为第一级负载均衡。

缺点是DNS生效时间略长,扩展性差。

基于IP的负载均衡,早期比较有代表性并且被大量使用的的就是LVS了。原理是LVS在Linux内核态获取到IP报文后,根据特定的负载均衡算法将IP报文转发到整个集群的某台服务器中去。

缺点是LVS的性能依赖Linux内核的网络性能,但Linux内核的网络路径过长导致了大量开销,使得LVS单机性能较低。

那么有没有更好的负载均衡技术呢?当然有。

Google于2016年3月最新公布的负载均衡Maglev就在此列。

Maglev是谷歌为自己的数据中心研发的解决方案,并于2008开始用于生产环境。在第十三届网络系统设计与实现USENIX研讨会(NSDI ‘16)上, 来自谷歌、加州大学洛杉矶分校、SpaceX公司的工程师们分享了这一商用服务器负载均衡器Maglev的详细信息。Maglev安装后不需要预热5秒内就能应付每秒100万次请求令人惊叹不已。在谷歌的性能基准测试中,Maglev实例运行在一个8核CPU下,网络吞吐率上限为12M PPS(数据包每秒),如果Maglev使用Linux内核网络堆栈则速度会小于4M PPS。

无独有偶,国内云服务商

进一步迭代了负载均衡产品——Vortex,成功地提升了单机性能。在技术实现上,UCloud Vortex与Google Maglev颇为相似。以一台普通性价比的x86 1U服务器为例,Vortex可以实现吞吐量达14M PPS(10G, 64字节线速),新建连接200k CPS以上,并发连接数达到3000万、10G线速的转发。

详情请见:

看带宽,一般来说nginx做负载比较简单,但单台服务器的带宽毕竟有限,1g了不起了,如果超过这个,就得用dns了,分片解析到一堆nginx,然后后面再挂负载均衡。在nginx流行之前,dns解析用的较多,主要是apache太弱了,以前相当于1级负载,现在中间加了一层nginx,2层结构,扩展更方便。另外业务也可以横向区分的,比如淘宝的图片服务器,除了负载均衡,还有cdn。

负载均衡一般分为两种,一种是基于DNS,另一种基于IP报文。利用DNS实现负载均衡,就是在DNS服务器配置多个A记录,不同的DNS请求会解析到不同的IP地址。大型网站一般使用DNS作为第一级负载均衡。基于IP的负载均衡,早期比较有代表性并且被大量使用的的就是LVS了。原理是LVS在Linux内核态获取到IP报文后,根据特定的负载均衡算法将IP报文转发到整个集群的某台服务器中去。

可以看看国防科技大学章文嵩博士的学位论文,章文嵩是lvs的作者,他现在是阿里云的负责人,2014年以前负责淘宝核心系统。

刚好最近写过这样的文章,相信你看了就彻底明白了

相信大家都听过这样的一道经典面试题:「请说出在淘宝网输入一个关键词到最终展示网页的整个流程,越详细越好」

这个问题其实很难,涉及到 HTTP,TCP,网关,LVS 等一系列相关的概念及工作机制,如果你能掌握到这其中的每个知识点,那将极大地点亮你的技能树,你对于网络是如何运作也会了然于胸,即便不能完全掌握,但知道流量怎么流转的对你排查定位问题会大有帮助,我之前就利用这些知识定位到不少问题,为了弄清楚整个流程,我查阅了很多资料也请教了不少人,相信应该可以把这个问题讲明白,不过写着写着发现篇幅实在太长,所以分为上下两篇来分别介绍一下,本篇先介绍流量在后端的的整体架构图,下一篇会深入剖析细节点,如 LVS 的工作细节,这其中会涉及到交换机,路由器的工作机制等

李大牛创业了,由于前期没啥流量,所以他只部署了一台 tomcat server,让客户端将请求直接打到这台 server 上

这样部署一开始也没啥问题,因为业务量不是很大,单机足以扛住,但后来李大牛的业务踩中了风口,业务迅猛发展,于是单机的性能逐渐遇到了瓶颈,而且由于只部署了一台机器,这台机器挂掉了业务也就跌零了,这可不行,所以为了避免单机性能瓶颈与解决单点故障的隐患,李大牛决定多部署几台机器(假设为三台),这样可以让 client 随机打向其中的一台机器,这样就算其中一台机器挂了,另外的机器还存活,让 client 打向其它没有宕机的机器即可

现在问题来了,client 到底该打向这三台机器的哪一台呢,如果让 client 来选择肯定不合适,因为如果让 client 来选择具体的 server,那么它必须知道有哪几台 server,然后再用轮询等方式随机连接其中一台机器,但如果其中某台 server 宕机了,client 是无法提前感知到的,那么很可能 client 会连接到这台挂掉的 server 上,所以选择哪台机器来连接的工作最好放在 server 中,具体怎么做呢,在架构设计中有个经典的共识:没有什么是加一层解决不了的,如果有那就再加一层,所以我们在 server 端再加一层,将其命名为 LB(Load Balance,负载均衡),由 LB 统一接收 client 的请求,然后再由它来决定具体与哪一个 server 通信,一般业界普遍使用 Nginx 作为 LB

采用这样的架构设计总算支撑了业务的快速增长,但随后不久李大牛发现这样的架构有点问题:所有的流量都能打到 server 上,这显然是有问题的,不太安全,那能不能在流量打到 server 前再做一层鉴权操作呢,鉴权通过了我们才让它打到 server 上,我们把这一层叫做网关(为了避免单点故障,网关也要以集群的形式存在)

这样的话所有的流量在打到 server 前都要经过网关这一层,鉴权通过后才把流量转发到 server 中,否则就向 client 返回报错信息,除了鉴权外,网关还起到风控(防止羊毛党),协议转换(比如将 HTTP 转换成 Dubbo),流量控制等功能,以最大程度地保证转发给 server 的流量是安全的,可控的。

这样的设计持续了很长一段时间,但是后来李大牛发现这样的设计其实还是有问题,不管是动态请求,还是静态资源(如 js,css文件)请求都打到 tomcat 了,这样在流量大时会造成 tomcat 承受极大的压力,其实对于静态资源的处理 tomcat 不如 Nginx,tomcat 每次都要从磁盘加载文件比较影响性能,而 Nginx 有 proxy cache 等功能可以极大提升对静态资源的处理能力。

画外音:所谓的 proxy cache 是指 nginx 从静态资源服务器上获取资源后会缓存在本地的内存+磁盘中,下次请求如果命中缓存就从 Nginx 本机的 Cache 中直接返回了

所以李大牛又作了如下优化:如果是动态请求,则经过 gateway 打到 tomcat,如果是静态请求,则打到静态资源服务器上

这就是我们所说的 动静分离 ,将静态请求与动态请求分开,这样 tomcat 就可以专注于处理其擅长的动态请求,而静态资源由于利用到了 Nginx 的 proxy cache 等功能,后端的处理能力又上了一个台阶。

另外需要注意的是并不是所有的动态请求都需要经过网关,像我们的运营中心后台由于是内部员工使用的,所以它的鉴权与网关的 api 鉴权并不相同,所以我们直接部署了两台运营中心的 server ,直接让 Nginx 将运营中心的请求打到了这两台 server 上,绕过了网关。

当然为了避免单点故障 Nginx 也需要部署至少两台机器,于是我们的架构变成了下面这样,Nginx 部署两台,以主备的形式存在,备 Nginx 会通过 keepalived 机制(发送心跳包) 来及时感知到主 Nginx 的存活,发现宕机自己就顶上充当主 Nginx 的角色

看起来这样的架构确实不错,但要注意的是 Nginx 是七层(即应用 层)负载均衡器 ,这意味着如果它要转发流量首先得和 client 建立一个 TCP 连接,并且转发的时候也要与转发到的上游 server 建立一个 TCP 连接,而我们知道建立 TCP 连接其实是需要耗费内存(TCP Socket,接收/发送缓存区等需要占用内存)的,客户端和上游服务器要发送数据都需要先发送暂存到到 Nginx 再经由另一端的 TCP 连接传给对方。

所以 Nginx 的负载能力受限于机器I/O,CPU内存等一系列配置,一旦连接很多(比如达到百万)的话,Nginx 抗负载能力就会急遽下降。

经过分析可知 Nginx 的负载能力较差主要是因为它是七层负载均衡器必须要在上下游分别建立两个 TCP 所致,那么是否能设计一个类似路由器那样的只负载转发包但不需要建立连接的负载均衡器呢,这样由于不需要建立连接,只负责转发包,不需要维护额外的 TCP 连接,它的负载能力必然大大提升,于是四层负载均衡器 LVS 就诞生了,简单对比下两者的区别

可以看到 LVS 只是单纯地转发包,不需要和上下游建立连接即可转发包,相比于 Nginx 它的抗负载能力强、 性能 高,能达到 F5 硬件的 60%;对内存和cpu资源消耗比较低

负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过负载均衡算法选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器 IP ),直接转发给该服务器。TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

综上所述,我们在 Nginx 上再加了一层 LVS,以让它来承接我们的所有流量,当然为了保证 LVS 的可用性,我们也采用主备的方式部署 LVS,另外采用这种架构如果 Nginx 容量不够我们可以很方便地进行水平扩容,于是我们的架构改进如下:

当然只有一台 LVS 的话在流量很大的情况下也是找不住的,怎么办,多加几台啊,使用 DNS 负载均衡在解析域名的时候随机打到其中一台不就行了

通过这样的方式终于可以让流量稳定流转了,有个点可能一些朋友会有疑问,下面我们一起来看看

如果不用 LVS 则架构图是这样的

通过部署多台 Nginx 的方式在流量不是那么大的时候确实是可行,但 LVS 是 Linux 的内核模块,工作在内核态,而 Nginx 工作在用户态,也相对比较重,所以在性能和稳定性上 Nginx 是不如 LVS 的,这就是为什么我们要采用 LVS + Nginx 的部署方式。

另外相信大家也注意到了,如果流量很大时,静态资源应该部署在 CDN 上, CDN 会自动选择离用户最近的节点返回给用户,所以我们最终的架构改进如下

架构一定要结合业务的实际情况来设计,脱离业务谈架构其实是耍流氓,可以看到上文每一个架构的衍化都与我们的业务发展息息相关,对于中小型流量没有那么大的公司,其实用 Nginx 作为负载均衡足够,在流量迅猛增长后则考虑使用 lvs+nginx,当然像美团这样的巨量流量(数十 Gbps的流量、上千万的并发连接),lvs 也不管用了(实测虽然使用了 lvs 但依然出现了不少丢包的现象)所以它们开发出了自己的一套四层负载均衡器 MGW

另外看了本文相信大家对分层的概念应该有更透彻的理解,没有什么是分层解决不了的事,如果有,那就再多加一层,分层使每个模块各司其职,功能解藕,而且方便扩展,大家很熟悉的 TCP/IP 就是个很好的例子,每层只管负责自己的事,至于下层是什么实现的上层是不 care 的

以上就是本文的全部内容,希望大家看了有收获^ ^,下一篇我们再继续深入探究一个请求的往返链路,会深入剖析 LVS,交换机,路由器等的工作原理,敬请期待 ^ ^

最后分享一套我看过的计算机经典书籍,都是非常经典的,涉及到网络,操作系统,数据结构和算法等,相信大家看了肯定有收获

外网智能路由是dns根据,用户所在地解析最快dns,一般结合cdn。内网一般nginx,apache反向代理,tomat动态请求实现负载均衡,负载均衡算法有,轮训nginx,apache轮训tomcat节点,请求转发过去,tocmat计算完后,在返回给nginx、apache。url一致性hash,根据url hash值将固定url打到固定节点计算。加权轮训,性能强机器权重大,流量大些,性能弱权中小,流量小些。

Google Maglev 牛逼的网络负载均衡器

我在这篇文章里介绍了下 3 层负载均衡的实现以及原理.

比较常用的还有 4 层负载均衡和 7 层负载均衡, 4 层开源的有 haproxy, 7 层就是 nginx 了, 它们两的原理简单说就是单点接收流量, 然后负载均衡到多个业务服务器

推荐一个网络压测工具dperf。

dperf 是一款性能强劲开源网络压力测试仪。性能可以达到100Gbps,每秒1千万TCP新建连接,几十亿TCP并发连接数。它不仅性能高,还能够实时准确发现网络中的丢包,非常适合测试防火墙、四层负载均衡(如LVS,DPVS、F5等),交换机,网卡、CPU、虚拟机的网络报文处理能力。

dperf 是基于DPDK框架,用C语言编写,目前代码量在9千行左右,有完整的设计文档、配置手册。dperf实现了小型TCP/UDP协议栈,支持IPV4、IPV6,也非常适合学习计算机网络的朋友们拿来做实验。

dperf 经Linux基金会评审,成为了DPDK生态项目。

如果想收藏此项目,请在项目主页点击star;如果想了解项目的最新进展,请点击watch;如果想贡献代码,请点击fork;如果在使用过程中有任何疑问或者有新的需求,请点击issue。

谢谢。

负载均衡分硬件层和软件层两种。

题主可以了解下LVS,这是现在很流行的开源负载均衡软件。