写点什么

聊聊 万亿流量场景下的负载均衡实践

作者:Java你猿哥
  • 2023-05-22
    湖南
  • 本文字数:4008 字

    阅读完需:约 13 分钟

性能为王。可用性和水平扩展,都要建立在性能优良的基础上才会去考虑。

性能是高并发的基础,而且涉及面极广,也是需要我们投入更多的精力去对待;同时,大部分优化点也是我们一线研发日常可以直接接触的模块。也是大厂面试的时候会经常涉及到的模块。

所以第一部分大概十几篇可能都会在垂直性能优化上。第一篇,垂直性能优化之细说集群部署和负载均衡。

从阿里架构演变来看负载均衡

我们将淘宝网的架构演进(即时通讯网)整理到一个滑动图里,如下图所示:












当然,比如中台建设、上云等更高级演进就在此忽略了;

可以更清晰的看到,在集群部署和负载均衡,几乎分布在了整个演进链路上最关键的节点上:

  • 当解决了本地存储的性能瓶颈,新的瓶颈出现在了 web 容器的单体性能上。因此,使用 nginx 反向代理来实现多个 web 容器负载均衡

  • 当数据库和 tomcat 都达到水平扩容,可支撑的并发大幅提升时,单体 nginx 代理的性能成了新的瓶颈。因此,使用 F5 或 LVS 来实现多个 nginx 反向代理服务器负载均衡

  • 当业务进一步发展,达到多地多机房部署,垮地域访问延迟成了新的瓶颈。因此,使用 DNS 来实现地域机房间的负载均衡

细说负载均衡方案

常见的实现方案,其实从上面的演进链路中也已经可以基本了解到各个方案适用的发展阶段和应对常见,这里再系统的总结下:

  • 基于 DNS 的负载

  • 基于硬件的负载,如 F5

  • 基于软件的负载,如 Nginx/Squid

DNS 负载



头条号[2] 知乎[3]

上面两副图,可以看到 DNS 的解析过程和负载均衡的原理。天然的优势就是配置简单,实现成本非常低,无需额外的开发和维护工作。

而缺点也比较明显:

  • 目前的 DNS 是多级解析的,每一级都可能缓存。所以生效不及时。

  • 不能按服务器的处理能力来分配负载。DNS 负载均衡采用的是简单的轮询算法,不能区分服务器之间的差异和运行状态,不灵活

  • 额外的网络问题。为了使本 DNS 服务器和其他 DNS 服务器及时交互,保证数据及时更新,一般都要将刷新时间设置的较小,可能造成流量增大。

基于硬件的负载均衡

「F5 Network Big-IP」 是一个网络设备,可以简单的认为是一个网络交换机一类的东西,性能非常好,百万级 TPS。

性能优良、功能强大,多种均衡算法都可以支持,还有防火墙等安全功能。但,非常贵,一般小公司可用不起。

基于软件的负载均衡

软件负载均衡都是以 TCP/IP 协议的 OSI 模型的运用:(即时通讯网[4])


根据 OSI 模型可将负载均衡分为:

  • 二层负载均衡(一般是用虚拟 mac 地址方式,外部对虚拟 MAC 地址请求,负载均衡接收后分配后端实际的 MAC 地址响应);

  • 三层负载均衡(一般采用虚拟 IP 地址方式,外部对虚拟的 ip 地址请求,负载均衡接收后分配后端实际的 IP 地址响应);

  • 四层负载均衡(在三次负载均衡的基础上,用 ip+port 接收请求,再转发到对应的机器);

  • 七层负载均衡(根据虚拟的 url 或是 IP,主机名接收请求,再转向相应的处理服务器)。

常见的其实只有 4 层和 7 层负载。

四层和七层的横向对比

四层七层原理基于 IP+端口基于虚拟的 URL 或主机 IP 分析内容 IP 层及 TCP/UDP 层应用层信息,如 HTTP 协议 URI 或 Cookie 信息复杂度架构简单、管理容易、问题定位方便比较复杂灵活性仅支持基于网络层的需求转发可对所有跟服务端的请求进行修改安全性无法直接抵御网络攻击更容易抵御来自网络的攻击效率基于更底层设置,效率高需要更多的资源损耗

常见的负载均衡算法

算法名优点缺点轮询简单高效,兼顾所有节点集群性能瓶颈更多的会受性能差的服务器影响随机同轮询类似一致性 hash 相同来源请求落点相同,有利于灰度发布等功能遇到热点会对节点有冲击;节点故障影响上游调用加权轮询将机器性能考虑在内,集群性能最大化生产环境复杂多变,无法动态调整权重,只能粗略预先优化动态连接数、最快响应动态,根据节点状况实时变化增大的复杂度和资源消耗

广义的负载均衡

上述内容基本都是基于服务级别来叙述的负载均衡的概念。其实,负载被运用的场景还很多,比如,服务端 rpc 选址、以及一些中间件的投递和请求分发,再有一些弹性架构下的弹性路由,单元化下的单元路由,其实也是更高层面的负载均衡。相应的,也有很多特定的负载算法,比如 rpc 中的本地优先负载等等。

下面分别就淘宝双 11、春运 12306、微信红包和抖音春晚红包等场景在负载均衡方面的运用进行一些介绍和讨论。

阿里双 11 流量下的负载均衡

双十一流量特点请求量巨大,脉冲式的。是对阿里生态链路上所有服务的考验对负载均衡器的要求:

  • 性能优良:应对双 11 当晚脉冲式的流量冲击

  • 服务稳定:可用性高,以应对设备和网络的抖动

  • 业务无感:顺滑的自身升级和容灾切换

实现原理

1)优良性能依赖 DPDK

阿里的新一代负载均衡器是基于 DPDK[2]来实现的。其优势总结如下


正是由于这些专门针对数据包的高性能支持,才得以实现性能优良的负载均衡器来支撑多年双 11 场景下的脉冲流量的压力。

2)应对 ECMP 重选导致的连接中断

ECPM(Equal-CostMultipathRouting) 是一种最大限度利用最短路径的等价多路径路由算法。



如上图,SLB 采用水平扩展的集群部署,多台服务器发布相同路由,在交换机处形成 ECPM 路由。以达到高可用的目的。,在连接没有同步之前,遇到服务器硬件或网络异常,会使该服务器不可用,ECPM 重选路由,会使连接到达其他服务器,导致已有连接中断,造成用户访问异常。SLB 使用了会话同步的机制来解决了升级与容灾场景下长连接中断的问题。用组播技术解决会话同步机制中的机器上下线问题。详细解释参见文献[1]。

铁路 12306 的负载均衡[4]

12306 大名鼎鼎,无需多介绍。其中很多的场景和技术都可以给我们做一些很好的参考。但只找到了 16 年发表的论文,没有能了解到最新的架构部署。

12306 的业务难点

  • 动态库存,余票可以按站点拆分

  • 事务强一致,下单交易性质

  • 多维度数据一致性,线上线下售票渠道

  • 流量洪峰,遇节假日有流量洪峰

这里对前几个问题就暂不讨论,单说负载均衡在应对流量洪峰时的作用。

12306 架构的发展历程如下:




由上图可以看到,第一次优化之前,几乎全链路服务都出现了性能瓶颈,因为并发查询导致查询系统负载过高,用户重试引发 AS 过载;AS 阻塞导致响应增加,引发 WEB 负载问题,线上压力导致整个票务系统异常,进而影响了线下购票渠道正常运转,直至链路雪崩。

第一次优化后,引入排队系统,不同车次使用不同队列,已达到请求分流;且排队系统采用了动态流量控制,根据各铁路局客票中心处理速度,进行控速请求下发;并进行了客票网服务拆分,根据不同规则,使流量负载均衡。此次优化让 12306 顺利度过了 13 年春运。但随着互联网的高速发展,网上订票人数不断增加,目前的架构已经达到了带宽、性能、稳定性的瓶颈。因此第二次优化如下:


本篇重点还是看负载均衡在业务场景下的实际作用,因此,其他优化点就不做讨论了。正是因为多维度,多层次的负载均衡,才使得 12306 能够承载更高的流量冲击(如果哪些同学有 12306 最新的部署架构,希望能私信交流学习~)

微信红包背后的负载均衡

2017 年正月,微信公布用户在除夕当天收发微信红包的数量——142 亿个,收发峰值已达到 76 万每秒。

百亿红包业务特点:

  • 不同于普通电商场景,一个群红包就相当于一个秒杀活动,并发要求更高

  • 金融属性,不允许数据出现一致性,安全级别要求更高。

那么微信的红包方案是怎么设计的

垂直 SET 化,分而治之

如果采用普通的服务拆分和部署方式,由于需要锁库存来防止超发,海量的锁竞争将对 DB 造成不可估量的压力。及时是使用外部存储的分布式锁进行前置压力缓解,只是对压力的转移,而无法减少。

采用 SET 化部署的好处,就是同一个红包只会被路由到同一个的 SET 内,相当于对庞大的洪流,进行了 reduce 似的细小拆分,不同的 SET 之间互不影响,极大的减少了不同 SET 之间的资源压力。(其实和阿里的 RGCzone 单元化部署原理差不多)


server 层请求排队

产生并发抢锁的原因,是因为到达 DB 的请求可能是并发,如果可以保证到达 DB 的请求穿行,那就不存在并发了。



首先,通过 IDhash 确保同一红包的请求被分配到同一台 Server,然后再进行单机红包排队,这样,就可以保证同一红包的请求顺序的达到 DB,从而减少 DB 抢锁并发。

双维度库表设计

因为红包数量巨大,单表数据达到一定程度就会出现性能问题;因此除了按红包 ID 分库分表,还按天进行冷热数据拆分,在保障数据可以优雅迁移的前提下,保证了当天的 DB 性能。而在查询时,通过数据库中间件,进行库表路由。

总结

从负载均衡的角度看红包的架构设计,可以看到,整个架构设计可以理解为使用了三层负载均衡,首先是入口层,将流量进行 set 拆分,达到整体 SET 集群的负载均衡;然后是 server 层,对红包 ID 进行业务逻辑 Hash ,ID 穿行的同时,达到 server 集群内部的负载均衡;再有是 DB 层,通过双维度库表设计,在保障 DB 性能的同时达到数据访问的负载均衡。

抖音春晚红包背后的负载均衡

前几部分分别从网络层、架构层、内部设计等角度阐述了负载均衡的实际运用。而这里会着重介绍下抖音架构中涉及到的下一代微服务技术 Service Mesh 在负载均衡上的优势。

什么是 Service Mesh

为了解决端到端的字节码通信问题,TCP 协议诞生,让多机通信变得简单可靠;微服务时代,Service Mesh 诞生,屏蔽了分布式系统的诸多复杂性,让开发者可以回归业务。







Service Mesh 下 Istio 的负载均衡[9]


Istio 服务网格在逻辑上分为控制平面和数据平面两部分。其中,数据平面由一组以 Sidecar 方式部署的智能代理(Envoy)组成,这些代理可以调节和控制微服务及 Mixer 之间所有的网络通信。


Envoy 代理可以发出很多指标和遥测数据,这些遥测数据发送到何处,取决于 Envoy 的配置.

Envoy 作为代理,在网络体系中扮演着中介的角色,可以为网络中的流量管理添加额外的功能,包括提供安全性、隐私保护或负载策略等。在服务间调用的场景中,代理可以为客户端隐藏服务后端的拓扑细节,简化交互的复杂性,并保护后端服务不会过载。并能发现集群中的所有成员,然后通过主动健康检查来确定集群成员的健康状态,并根据健康状态,通过负载均衡策略决定将请求路由到哪个集群成员。

结束语

本篇从实践的角度出发,挑选了四个最典型的案例,分别从网络层、架构层、微服务发展等方面阐述了负载均衡的实际运用,希望能对大家的工作和学习有所帮助~

用户头像

Java你猿哥

关注

一只在编程路上渐行渐远的程序猿 2023-03-09 加入

关注我,了解更多Java、架构、Spring等知识

评论

发布
暂无评论
聊聊 万亿流量场景下的负载均衡实践_负载均衡_Java你猿哥_InfoQ写作社区