极客时间已完结课程限时免费阅读

35 | 流量调度与负载均衡

35 | 流量调度与负载均衡-极客时间

35 | 流量调度与负载均衡

讲述:丁伟

时长10:32大小9.63M

你好,我是七牛云许式伟。
相比桌面程序而言,服务端程序依赖的基础软件不只是操作系统和编程语言,还多了两类:
负载均衡(Load Balance);
数据库或其他形式的存储(DB/Storage)。
为什么会需要负载均衡(Load Balance)?今天我们就聊一下有关于流量调度与负载均衡的那些事情。
上一讲我们画了服务端程序的体系架构图,如下:
什么是 “流量调度”?我们首先要了解这样几个常见的服务端程序运行实例(进程)相关的概念:
连接数;
IOPS;
流量,入向流量和出向流量。
我们知道,一个基本的服务端程序的服务请求,通常是由一个请求包(Request)和一个应答包(Response)构成。这样一问一答就是一次完整的服务。
连接数,有时候也会被称为并发数,指的是同时在服务中的请求数。也就是那些已经发送请求(Request),但是还没有收完应答(Response)的请求数量。
IOPS,指的是平均每秒完成的请求(一问一答)的数量。它可以用来判断服务端程序的做事效率。
流量分入向流量和出向流量。入向流量可以这么估算:
平均每秒收到的请求包(Request)数量 * 请求包平均大小。
同样的,出向流量可以这么估算:
平均每秒返回的应答包(Response)数量 * 应答包平均大小。
不考虑存在无效的请求包,也就是存在有问无答的情况(但实际生产环境下肯定是有的)的话,那么平均每秒收到的请求包(Request)数量、平均每秒返回的应答包(Response)数量就是 IOPS。故此:
入向流量 ≈ IOPS * 请求包平均大小
出向流量 ≈ IOPS * 应答包平均大小
所谓流量调度,就是把海量客户并发的请求包按特定策略分派到不同的服务端程序实例的过程。
有很多手段可以做流量调度。

DNS 流量调度

最基础的方式,是通过 DNS,如下图所示。
一个域名通过 DNS 解析到多个 IP,每个 IP 对应不同的服务端程序实例。这样就完成了流量调度。这里我们没有用到常规意义的负载均衡(Load Balance)软件,但是我们的确完成了流量调度。
那么这种做法有什么不足?
第一个问题,是升级不便。
要想升级 IP1 对应的服务端程序实例,必须先把 IP1 从 DNS 解析中去除,等 IP1 这个实例没有流量了,然后我们升级该实例,最后把 IP1 加回 DNS 解析中。
看起来还好,但是我们不要忘记,DNS 解析是有层层缓冲的。我们把 IP1 从 DNS 解析中去除,就算我们写明 TTL 是 15 分钟,但是过了一天可能都还稀稀拉拉有一些用户请求被发送到 IP1 这个实例。
所以通过调整 DNS 解析来实现升级,有极大的不确定性,完成一个实例的升级周期特别长。
假如一个实例升级需要 1 天,我们总共有 10 个实例,那么就需要 10 天。这太夸张了。
第二个问题,是流量调度不均衡。
DNS 服务器是有能力做一定的流量均衡的。比如第一次域名解析返回 IP1 优先,第二次域名解析让 IP2 优先,以此类推,它可以根据域名解析来均衡地返回 IP 列表。
但是域名解析均衡,并不代表真正的流量均衡。
一方面,不是每次用户请求都会对应一次 DNS 解析,客户端自己有缓存。另一方面,DNS 解析本身也有层层缓存,到 DNS 服务器的比例已经很少了。
所以在这样情况下,按域名解析做流量调度均衡,是非常粗糙的,实际结果并不可控。
那么,怎么让流量调度能够做到真正均衡?

网络层负载均衡

第一种做法,是在网络层(IP 层)做负载均衡。
章文嵩博士发起的负载均衡软件 LVS(Linux Virtual Server)就工作在这一层。我们以 LVS 为代表介绍一下工作原理。
LVS 支持三种调度模式。
VS/NAT:通过网络地址转换(NAT)技术做调度。请求和响应都会经过调度器中转,性能最差。
VS/TUN:把请求报文通过 IP 隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。这种做法性能比 VS/NAT 好很多。
VS/DR:通过改写请求报文的 MAC 地址,将请求发送到真实服务器,真实服务器将响应直接返回给客户。这种做法相比 VS/TUN 少了 IP 隧道的开销,性能最好。
我们重点介绍下 VS/DR 技术。
如上图所示。设客户端的 IP 和 MAC 为 CIP、CMAC。
第 1 步,客户端发起请求,其 IP 报文中,源 IP 为用户的 CIP ,目标 IP 是 VIP;源 MAC 地址为 CMAC ,目标 MAC 地址为 DMAC。
第 2 步,请求包到达 LVS 调度器(Director Server)。我们保持源 IP 和目标 IP 不变,仅仅修改目标 MAC 地址为 RMAC,将请求转发到真实的业务服务器实例 RS(Real Server)。
第 3 步,RS 收到数据包并经过处理,直接响应发送给客户端。
这里面的关键技巧,是 VIP 绑定在多台机器上,所以我们把它叫做虚拟 IP(Virtual IP)。它既绑定在 LVS 调度器(Director Server)上,也绑定在所有的业务服务器实例 RS(Real Server)上。
当然这里有一个很重要的细节是,ARP 广播查询 VIP 对应的 MAC 地址得到什么?答案当然是 LVS 调度器(Director Server)。在真实的业务服务器实例 RS(Real Server)上,我们把 VIP 绑定在 lo 接口上,并对 ARP 请求作了抑制,这样就避免了 IP 冲突。
LVS 这种在网络层底层来做负载均衡,相比其他负载均衡技术来说,其特点是通用性强、性能优势高。
但它也有一些缺点。假如某个业务服务器实例 RS 挂掉,但 LVS 调度器(Director Server)还没有感知到,在这个短周期内转发到该实例的请求都会失败。这样的失败只能依赖客户端重试来解决。

应用层负载均衡

有办法避免出现这种请求失败的情况吗?
可以。答案是:服务端重试。
怎么做服务端重试?应用层负载均衡。有时候我们也把它叫做应用网关。
HTTP 协议是应用最为广泛的应用层协议。当前应用网关,绝大多数都是 HTTP 应用网关。
Nginx 和 Apache 都是大家最为耳熟能详的 HTTP 应用网关。因为知道应用层协议的细节,所以 HTTP 应用网关的能力通常非常强大。这一点我们后面还会进一步进行探讨,今天我们先聊负载均衡(Load Balance)相关的内容。
HTTP 网关收到一个 HTTP 请求(Request)后,根据一定调度算法把请求转发给后端真实的业务服务器实例 RS(Real Server),收到 RS 的应答(Response)后,再把它转发给客户端。
整个过程的逻辑非常简单,而且重试也非常好做。
在发现某个 RS 实例挂了后,HTTP 网关可以将同一个 HTTP 请求(Request)重新发给其他 RS 实例。
当然一个重要的细节是为了能够支持重试,HTTP 请求(Request)需要被保存起来。不保存 HTTP 请求做重试是有可能的,但是只能支持业务实例完全挂掉 HTTP 请求一个字节都没发过去的场景。但在断电或异常崩溃等情况,显然会有很多进行中的请求是不符合这个前提的,它们就没法做重试。
大部分 HTTP 请求不大,直接在内存中存储即可,保存代价不高。但是文件上传型的请求,由于请求包中包含文件内容,可能就需要依赖临时文件或其他手段来保存 HTTP 请求。

优雅升级

有了负载均衡,不只是可以实现了流量的均衡调度,连带业务服务器的升级也会方便多了。
对于前端是 LVS 这种网络层负载均衡的场景,升级的核心步骤为:
升级系统通知 LVS 调度器(Director Server)下线要升级的业务服务器(Real Server)实例。
LVS 调度器(Director Server)将该实例从 RS 集合中去除,这样就不再调度新流量到它。
升级系统通知要升级的 RS 实例退出。
要升级的 RS 实例处理完所有处理中的请求,然后主动退出。
升级系统更新 RS 实例到新版本,并重启。
升级系统将 RS 实例重新加回 RS 集合参与调度。
对于前端是 HTTP 应用网关这种负载均衡的场景,升级的过程可以更加简单:
升级系统通知升级的业务服务器(Real Server)实例退出。
要升级的 RS 实例进入退出状态,这时新请求进来直接拒绝(返回一个特殊的 Status Code);处理完所有处理中的请求后,RS 实例主动退出。
升级系统更新 RS 实例到新版本,并重启。
可以看出,因 HTTP 应用网关支持重试,业务服务器的升级过程就变得简单很多。

结语

今天我们从流量调度谈起,聊了几种典型的调度手段和负载均衡的方式。
从流量调度角度来说,负载均衡的最大价值是让多个业务服务器的压力均衡。这里面隐含的一个前提是负载均衡软件的抗压能力往往比业务服务器强很多(为什么?欢迎留言讨论)。
这表现在:其一,负载均衡的实例数 / 业务服务器的实例数往往大大小于 1;其二,DNS 的调度不均衡,所以负载均衡的不同实例的压力不均衡,有的实例可能压力很大。
当然,负载均衡的价值并不只是做流量的均衡调度,它也让我们的业务服务器优雅升级成为可能。
如果你对今天的内容有什么思考与解读,欢迎给我留言,我们一起讨论。下一讲我们将聊聊存储中间件。
如果你觉得有所收获,也欢迎把文章分享给你的朋友。感谢你的收听,我们下期再见。
分享给需要的人,Ta购买本课程,你将得20
生成海报并分享

赞 27

提建议

上一篇
34 | 服务端开发的宏观视角
下一篇
36 | 业务状态与存储中间件
unpreview
 写留言

精选留言(42)

  • Geek_4b2920
    2019-08-24
    讲到lvs时说到"有办法避免出现这种请求失败的情况吗?",接着就说nginx是怎么去做的,感觉这里不太衔接呢,lvs不能做服务端重试?还是什么原因?没太明白

    作者回复: lvs 不太好做,在 VS/DR 模式下应答包(response)根本就不经过它,所以它连请求包(request)是否已经应答都不知道,就别提失败后重试了。如果在 VS/NAT 模式下,它也需要理解应用层的协议后才能重试,那它就不是网络层负载均衡,而是应用层负载均衡了。

    共 4 条评论
    26
  • dovefi
    2020-06-21
    总结一下: 1. dns 负载均衡 优点:没有服务器额外开销,没有流量瓶颈 缺点:变更延时高,流量均衡能力弱,没有重试 2. LVS 四层均衡 优点: 只处理入向流量,减小了流量瓶颈的问题,切换升级容易,调度容易 缺点:由于出向流量不经过lvs,所以没办法做重试的功能, 3. nginx 七层负载均衡 优点:完美解决负载均衡的问题,解决请求重试问题,同样可以做到无感知服务端升级 缺点:容易成为流量瓶颈,很依赖负载均衡的性能 一般的架构都是 LVS + nginx 的模式
    展开

    作者回复: 一般三个都会同时用

    共 2 条评论
    21
  • williamcai
    2019-08-27
    lvs调度器和业务服务器都用vip,请求过来了,它怎么通过vip找到的是调度器,而不是业务服务器

    作者回复: 文章中有解释,arp 协议是通过 ip 得到 mac,这时只有调度器响应 arp。也就是说,在全局,vip 是被认为绑在调度器上。只有各个业务服务器自己以为自己也绑了vip。

    共 2 条评论
    9
  • Void_seT
    2019-08-23
    1、首先,因为绝大多数情况下负载均衡服务器的简单转发消耗的系统资源更少,而业务逻辑的处理往往需要更多的系统资源,那么,在服务器配置相当的情况下,负载均衡服务器就比业务处理服务器能处理更多的请求; 2、如果,负载均衡服务器的处理能力与业务处理服务器的处理能力相当,那这种依靠负载均衡服务器来做负载均衡的方式效率就极低(约为50%),资源使用率也很低(约为50%),那么,在架构演进的过程中,这种负载均衡方式一定会被淘汰,取而代之的会有目前httpdns等其他的负载均衡方式。
    展开
    7
  • CoderLim
    2019-08-23
    负载均衡软件的抗压能力往往比业务服务器强很多,为什么? 负载均衡的功能只是转发,相对简单,没有耗时操作,主要的瓶颈应该是最大连接数和内存
    5
  • 王棕生
    2020-06-27
    许老师,lvs 是工作在IP层,也就是不断接受IP数据包,然后转发到业务服务器;如果同一个TCP 包中几个IP数据包被转发到了不同的业务服务器怎么办?lvs 是怎么控制的呢?还有关于F5是怎么保证的没?
    共 1 条评论
    5
  • 喆里
    2020-04-25
    请教下,上面的说两种负载均衡方式LVS和http应用网关,在实际应用中,是不是LVS后面的RS对应的就是http应用网关实例, http网关实例后面的RS才是真正的业务实例?

    作者回复: 这样做是靠谱的

    5
  • leslie
    2019-08-23
    老师今天说的都是前端的:可是好像负载均衡不止这些吧,软件一旦并发高了不是从整体的去做均衡么,不仅仅是这些吧?就像数据库方面我经常会去做一主多从、读写分离,甚至说软硬件很多时候都会做相应的事情,可是总觉得这个如何去整体的把握这种均衡确实觉得不容易把握。 老师的课程一路断断续续努力学到现在整体的收获还是让我感觉不一样:如果可以的话,希望老师对于负载均衡这个问题进行适当的扩展,可能这是大多从业到一定年份的IT从业者会碰到的一个困惑问题,这个合理性确实有时很难整体合理的把握。
    展开

    作者回复: 存储的扩展不是基于负载均衡,这个下一讲就会有所涉及。

    共 2 条评论
    4
  • 不温暖啊不纯良
    2021-06-07
    老师在文章中提到的DNS流量调度,是不是就相当于是客户端的负载均衡?就像Spring cloud的里面的Ribbon一样?因为ribbon也是客户端拿到所有服务的IP列表,然后在客户端根据负载均衡算法去请求对应的服务,如果不是那么ribbon再进行服务升级的时候,是不是也存在DNS流量调度那样的问题? 我在网上搜了一下,负载均衡有客户端的负载均衡,也有服务端的负载均衡,它们两个之间的优缺点到底是啥?
    展开

    作者回复: dns负载均衡并不是客户端负载均衡,但是和客户端负载均衡的原理的确比较像。客户端负载均衡是很难做精细均衡,因为它只看到自己,看不到其他客户端,不像服务端可以对所有客户做均衡。两者一般是配合关系,负载均衡的入口ip通常有多个,通过dns或客户端先做一次初步的均衡,再通过服务端负载均衡做精细均衡。

    共 2 条评论
    4
  • humor
    2019-08-26
    lvs调度器怎么做到只是修改了mac地址就能找到要转发的业务服务器的呢?我理解的网络层的转发是要先通过mac拿到ip,才能找到对应的机器的

    作者回复: 反过来了,是通过ip拿到mac。

    共 3 条评论
    4
  • 氧气🌙 🐟 🌺
    2019-12-14
    这里面隐含的一个前提是负载均衡软件的抗压能力往往比业务服务器强很多。 由上面一问引发的问题:全球DNS服务器的性能怎样,如何能撑得住全球并发访问?我猜想访问压力也不是直接分散,而是逐个梯次缓存,类似于硬盘,内存,缓存,寄存器等逐级释放。

    作者回复: 是这样

    2
  • 居培波
    2019-08-28
    中小型产品(项目)用Nginx+Tomcat完成简单负载均衡部署,nginx不需要处理产品业务需求,只需转发客户端请求即可。利用Nginx高并发、轻量级等特征满足一定用户量的增长。
    2
  • 业余爱好者
    2019-08-23
    负载均衡软件就是为了流量调度而生的,它主要是将请求路由到应用服务器,相比而言,应用服务器多了负载的业务处理这一步,所以抗压能力不如负载均衡软件。
    2
  • 不温暖啊不纯良
    2021-04-20
    分别介绍了DNS流量调度。 Lvs网络层负载均衡。还有基于HTTP协议的应用层的负载均衡。 从来没有真正体验过负载均衡带来的好处,因为我们是做政务项目的,并发量比较低,虽然用nginx做的负载均衡和反向代理,但对这些技术的认知还停留在表面。 负载均衡为什么要以单个业务服务器的抗压能力大?因为所有请求都是通过他分发给业务服务器的,也就是说我有10个服务器,每个服务器处理100个请求,但是负载均衡服软件要能够。处理1000个请求,所以他有内存足够大。 关于DNS ,lvs,HTTP网关, Lvs和HTTP网关,老师介绍过了,一个是应用在网络层,一个是应用在应用层面,但是他们不都是为了处理用户请求吗,他们之间是一起处理用户的请求吗?还有DNS他们之间的关系是什么样的?虽然说各有优缺点,但我看老师说,在一般业务中这三个都要用,我都没有见识过。 没有理解老师这段话的意思。 这表现在:其一,负载均衡的实例数 / 业务服务器的实例数往往大大小于 1;其二,DNS 的调度不均衡,所以负载均衡的不同实例的压力不均衡,有的实例可能压力很大。
    展开
    1
  • 右耳朵猫咪
    2021-03-24
    七牛云能顶住每天亿万级的视频文件存储吗,比如像快手、抖音那样的。

    作者回复: 这个必须没问题啊😄

    共 2 条评论
    2
  • ::error
    2020-05-24
    每一次都觉得自己对计算机网络很了解了,可是每一次看到高手写的文章,都刷新一次对计算机网络的认识!!
    1
  • Messi Curry
    2020-05-10
    首先负载均衡存在的意义主要是为了帮服务器分压,假设负载均衡抗压能力=业务服务器,那将是一个巨大成本的浪费,这样会导致它的数量必须要少,同样的请求量,数量小就要意味着更高的并发支持。再者,负载均衡主要负责根据权重进行策略转发,不承载业务服务器那种逻辑处理,也没有跟各个中间件和数据库的过多交互,高并发的实现是顺理成章的。
    1
  • edward
    2019-12-12
    老师,你好,想请问一下,我在数据中心中部署了5台服务器和F5做负载均衡,现在遇到一个问题,某个经办点有很多用户,他们是通过nat的形式访问我们的负载地址,导致整个经办点的用户请求都压在一台机子上,这种情况下,选择哪种负载方式可以解决这种情况,让来自一个经办点的用户的请求能均匀转发到5台服务器上?

    作者回复: 这个主要要改负载均衡的配置,不要按ip来分派请求

    1
  • Aaron Cheung
    2019-08-23
    学习了 业务流量不大……肿么办
    共 1 条评论
    1
  • 许童童
    2019-08-23
    老师这一节讲得很好,服务优雅升级配合负载均衡确实是很不错的解决方案。
    1