从底层技术来看,GSLB 究竟难在哪儿-阿里云开发者社区

开发者社区> 【云行】> 正文

从底层技术来看,GSLB 究竟难在哪儿

简介: 本文作者吕宏利来自硅谷的SRE,有着多年的国内外大型互联网公司运维开发经验,专注于分布式系统设计、监控、容量规划,数据中心技术以及生产环境的最佳实践。在本文中他将他将向读者介绍什么是GSLB,以及实现细节和维护方法。
+关注继续查看

原文转载自:高效运维社区 作者:吕宏利


作者简介

吕宏利,来自硅谷的SRE,多年的国内外大型互联网公司运维开发经验,专注于分布式系统设计、监控、容量规划,数据中心技术以及生产环境的最佳实践。

GSLB是什么

GSLB 一种常见的解释是 Global Server Load Balancing 的缩写,也有说法是 Global Software Load Balancing 或者 Global Site Load Balancing,翻译过来就是:全局服务/软件/站点负载均衡。

根据维基百科:负载均衡可以促进工作负载在多个计算资源之间的分配,比如:计算机之间、计算集群直接、网络链路、CPUs 或者磁盘。目的是优化资源使用率,最大化吞吐量,最小化响应时间,并且避免任何单一资源的过载。维基百科的定义偏重于负载分配以优化资源使用率,大型互联网公司应用 GSLB 还有另外2个很重要的目标:

  • 提高系统的可用性(availability)当某个站点/集群整体不可用时,系统仍然可以通过其他站点/集群提供完整可用的服务
  • 降低用户的访问延迟(latency)根据用户地理位置,将请求发送到最近的站点/集群提供服务,降低用户的请求延迟,改进用户体验

Why it’s hard

首先定义一下“hard”:这里并不是指很难实现/搭建一套 GSLB 系统,而是指实现/搭建一套可以达到开篇提到的三个目标的 GSLB 系统很难。为什么说很难呢,我尝试从三个大的方面去解释:

  • 从底层技术上
  • 从运行维护上
  • 从功能实现上

由于篇幅较长,整篇文章会分为三个部分,本文是第一部分,从使用的底层技术入手解释为什么很难。

从底层技术上

这里我们主要讨论基于 DNS 的 GSLB,因为 DNS 是最古老也是应用最广泛的全局负载均衡方式,支持所有上层协议的全局负载。几乎所有的 GSLB 实现都离不开 DNS,不夸张的说很多简单的 GSLB 就是通过 DNS 实现的。复杂一些的 GSLB 还会增加其他组件,但是 DNS 会作为第一层的负载均衡。如果只谈论 HTTP 协议的全局负载均衡,还有基于 HTTP 重定向的 GSLB 系统,但是该方案的局限性也很大,这里不做过多讨论。下面这张图是一个最简单的 GSLB 架构图

bd2720a1e23d725a9b98670c749a8939290bb9f9

我们以用户访问 www.example.com 为例来解释上图,图中有两个很重要的信息流:

  1. local balancer 上报数据给 global balancer,global balancer 汇总 local balancer 上报的数据,并将汇总后的数据发给权威 DNS,权威 DNS 会根据 global balancer 上报的数据调整返回给用户的 IP 地址;
  2. 用户打开浏览器,通过 ISP DNS 递归查询网址 www.example.com 对应的 IP 地址,最终权威服务器会返回一个 IP 地址给 ISP DNS,ISP DNS 返回 IP 给用户,浏览器发送请求到IP地址对应的服务器集群;

基于DNS负载均衡的问题

图一是张很简单的 GSLB 架构图,图中 NYC 和 LON 用户各自访问距离最近的服务,这是理想状态,在现实中要维持这种状态是有很多问题需要解决的。

1. 如何返回最优IP

一般情况下,example.com 的 DNS 权威服务器可以根据源请求 IP 返回最近的example.com 集群 IP,对应到上图中就是 NYC 的用户得到的 example.com 集群 IP 实际是根据本地ISP DNS的IP返回的。这就涉及了一个问题,如果本地ISP没有 DNS 服务器而是使用其他上级 ISP 的 DNS 服务器,NYC 的客户端就有可能得到距离很远的集群IP(假如本地ISP使用了多伦多的ISP进行DNS递归查询);或者用户自己设置了其他公共 DNS 服务器,都会导致返回的IP地址不是最优的。

当然了,现在我们有 edns-client-subnet,如果本地 ISP DNS 或其他公共 DNS支持,那么客户端就可以得到距离最近的集群 IP 来提供服务。可以通过以下链接查看支持 edns-client-subnet 的大型 DNS 服务提供者:http://www.afasterinternet.com/participants.htm。上面这个列表肯定是不全的,不是所有公司都会更新这个名单,不管这也传达了一个信息,edns-client-subnet 的普及速度很慢。

2. 如何准确分流

简单基于 DNS 的负载均衡方案,另外一个很大的弊端是流量分配不均。原因主要有下面2点:

  • ISP DNS—DNS 解析结果会被缓存,一个DNS请求可能对应到成百上千个服务请求。
  • 缺乏广泛的 edns-client-subnet 支持—这不仅会导致流量的跨地区访问,还会严重影响用户体验。用户手动设置 DNS 服务器,得不到最优 IP 解析。小 ISP 使用其他异地ISP的 DNS,得不到最优 IP 解析

由于服务提供者,比如 Google,很难控制用户自己的 DNS 设置以及广大 DNS 服务提供者对 edns-client-subnet 的支持,如何调整流量就必须从服务端进行了。

944535bacc165aa83770800f50400e5fca2bd548

如图二所示,服务端balancer信息流新增了一个环节。global balancer根据每个集群的容量和已有请求进行集群间的流量迁移。这对 GSLB 系统提出2个新的要求:

  1. local balancer上报的数据有新的要求,不仅要上报本地集群的容量还要对收到的流量进行上报,这样 global blancer 就可以根据每个集群容量和负载进行集群间的流量调配了。
  2. local balancer 要能够转发远大于本地集群容量的请求,这样才能在满足本地集群负载的情况下,转发多余的请求到其他集群。

这其实是在服务器端构建了一个反馈回路,local/global balancer 可以根据集群容量、负载进行流量调配,消除了由于 DNS 调度导致的热点集群问题。还可以通过集群健康数据的收集,在流量调度时过滤问题集群。另外一种可行的方案是,服务器端在收到用户请求时判断用户是否在访问最优的集群,如不是最优集群就重定向用户 到距离最近/最优的集群。

判断方法也比较简单,比如服务器端进行 RTT 的对比,如果 RTT 大于一定阈值就向自己的权威服务器提交客户 IP 查询更优结果,然后创建一个基于 FQDN 的重定向。就像当年 Akamai 做的那样:https://blogs.akamai.com/2013/03/intelligent-user-mapping-in-the-cloud.html。这种方法对某些业务形态比较有效,比如长时间的视频流或下载业务,初始的那个额外重定向和 DNS 查询时间占比很小,但是性能改进很大;如果是短暂的HTTP请求,效果就不明显了。

有吃瓜群众会问了:HttpDNS 可以解决这个问题吧?如果你的服务是通过可控客户端提供的,那么 HttpDNS 可以帮助你解决这个问题,因为你也修改客户端使用 HttpDNS。但是如果你的服务是通过浏览器提供的,那么 HttpDNS 是帮不上忙的,不过基于 HTTP 重定向的 GSLB 可以,但是该方案本身的实现难度和问题也不小,而且支持的业务形态比较单一,目前我没有见过哪个公司大规模部署这个方案,如果有谁知道可以探讨一下。

3. 如何快速切流

事故是一定会发生的,如何在事故发生时快速切走流量,将用户的影响降到最低是至关重要的。

44d6a5b7ccb525dc49e8feca9753c3712eedfbcd

然而,基于DNS的切流机制是不靠谱的。

  • 客户端的DNS缓存,i.e 浏览器、操作系统
  • ISP DNS或公共DNS服务的缓存
  • 不遵循DNS TTL的DNS服务或客户端

即便是能在第一时间更新权威服务器,不再返回故障集群的 IP,由于以上原因,还是会有一段时间(从几分钟到几小时不等)请求仍然发送到故障集群,导致请求失败。如果故障集群的 local balancer 还可用,那么集群间的流量调度可以很快切走流量,这里主要讨论 local balancer 也不可用的情况。

要解决这个问题,最好的方案是通过 anycast,每个集群通过 BGP 对外通告同样的 VIP,互联网上的路由器会最终根据通告的 VIP 距离判断路由的优先级。所有用户对 www.example.com 的 DNS 请求都会返回同样的 VIP 地址,但是不同区域用户对VIP的请求会被路由到各自最近的集群。当某个集群出现故障时,该集群对外通告的 VIP 会被撤回,路由更新之后,之前该集群服务的用户请求会被自动路由到次优集群,这对用户来说都是透明的,但是如果提供的服务是有状态的,会导致状态丢失,比如 youtube 视频播放会中断。

如果不能部署 anycast 呢?来看看 Dyn 的 DNS 服务提供的 anycast 接入点你就明白了

549a3b99a33b19d3d8336f3ab7245292802712f8

Dyn Anycast

还有另外一种方法是通过 BGP 的 community 为集群的IP地址段设置主备路由,备份路由的目的地是另外一个集群。DNS 权威服务器根据用户所在区域和集群容量信息返回集群的 VIP,正常请下对该 VIP 的数据包会被路由到本集群,当该集群故障时,备份路由生效,从而流量会被路由到其他健康的集群,同样会对有状态服务造成影响。

上面两种方法都属于从网络层弥补应用层负载均衡的缺陷,可以规避DNS切流慢的问题。

延迟控制系统

当你的 GSLB 系统具备了内部集群间的流量调度功能时,形成了一个反馈闭环,整个 GSLB 系统就具备了控制系统的特征,而且还是具有延迟的控制系统。

b6572980ca85397c19e5a1f1e7a5ddd2cd0a9291

上图去掉了互联网部分,只关注 GSLB 本身的主要构成,以4个集群为例。信息流动过程为:

  1. 本地集群的各个服务向 local balancer 汇报当前负载
  2. 向 global balancer 汇报所有本地服务的负载和容量(服务 owner 提前配置)
  3. global balancer 收集到所有 local balancer 的上报之后计算出如何分配集群间的流量
  4. global balancer 下发流量调配指示;更新权威 DNS 服务器
  5. local balancer 调整流量分配
  6. 回到步骤1

然而整个过程不是瞬间完成的,如图中所示:本地服务每10秒钟上报一次负载,本地 balancer 每5秒钟上报一次,本地 balancer 可以在上报的 RPC 请求结果中拿到流量分配指示。由于 global balancer 不可能实时计算所有集群所有服务的流量分配情况,所以本地 balancer 拿到的分配指示和本次上报是没有任何关系的,流量分配指示是根据历史数据计算出来的,WTF?!

一个全球系统

你虽然可以通过调整上报时间间隔和 global balancer 的计算频率来缩小差距,但是考虑到这是一个全球性的系统,为了正确调度 global balancer 需要所有集群的数据,有几个问题是无法避免的:

  • 数据中心间的网络延迟
  • 频繁上报、下发导致的跨网流量
  • 大量上报数据对计算能力和实时性的要求

基本上就是一个权衡各种因素,最终选择一个合适的这种配置,就将就着用旧点的数据做流量调整吧!

不能处理短暂的峰值

不能避免延迟,一个最大的问题就是:GSLB在面对短暂的流量峰值时是无能为力的。所以,一般的 GSLB 系统有一个假设:服务的流量在很短时间内不会出现剧烈变化。

以上图为例,如果 NYC 集群突然受到超过集群容量的请求(比如短暂的 DDoS),但是只持续了5秒钟的时间,这个峰值很可能都不会被 local balancer观测到。但是,如果你的服务由于过载导致进程重启,但是需要较长时间恢复,从而 NYC 集群容量减少,十几秒钟之后流量被分配到其他集群,如果期间还有多次的短暂峰值会将你的服务推向雪崩或者进入全球超负荷运行状态。上面的结论是基于一个前提条件:local balancer 并不在请求路径上。如果local balancer在请求路径上呢,那么先挂掉的可能是 local balancer,随之而来的是服务的全球超负荷运行。

你可能会说,难道没有 DDoS 防护措施吧,当然有了,但是 DDoS 的介入也是需要满足一定条件的,这种瞬时的流量峰值很难触发。我对 DDoS 防护手段研究不深,但是根据经验觉得可能不会触发,因为触发 DDoS 保护也需要历史和当前的流量信息,而这些信息很可能就是 GSLB 系统提供的,如果 GSLB 系统本身检测不到又怎么传递给 DDoS 系统呢。

小结

本节从 GSLB 最普遍的 DNS 负载均衡开始,介绍了基于 DNS 的 GSLB 系统面临和可以解决/改进的问题:

  • 改进 DNS 协议本身和应用,改进 IP 分配的精确度。效果明显,但是进度缓慢;edns-client-subnet RFC的提出,以及客户端、服务器端的实现。
  • 引入服务器端反馈回来,改进 DNS 缓存、IP 分配不准确带来的流量不均;一套企业内部服务集群间的 GSLB 系统,和外部 GSLB 系统联动。
  • 借助网络层技术手段进行快速切流;Anycast 以及备份路由。

以及 GSLB 系统固有的难以解决的问题:

  • 延迟控制系统
  • 全球系统
  • 对流量的假设

从传统IT部署到云,人肉运维已经是过去式,云上运维该怎么开展?尤其是云2.0时代,运维已经向全局化、流程化和精细化模式转变。与此同时,人工智能的发展,“威胁论”也随之袭来——运维是不是快要无用武之地了?如何去做更智能的活?4月20日晚2017运维/Devops在线技术峰会告诉你!免费!有料!快点这里报名(https://yq.aliyun.com/activity/188

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
6510 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4073 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7656 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
9351 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
2971 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
16420 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
813 0
+关注
【云行】
下载频道官方账号。
84
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载