循环 DNS 是否“足够好”用于负载平衡静态内容?

Jef*_*ood 67 domain-name-system load-balancing redundancy

我们在http://sstatic.net的网站之间提供一组共享的静态内容。不幸的是,此内容目前根本没有负载平衡——它是从单个服务器提供的。如果该服务器出现问题,则所有依赖它的站点都会有效关闭,因为共享资源是必不可少的共享 javascript 库和图像。

我们正在寻找在此服务器上负载平衡静态内容的方法,以避免单服务器依赖。

我意识到循环 DNS 充其量只是一个低端(有些人甚至可能会说是贫民窟)解决方案,但我不禁想知道——循环 DNS 是否是静态内容基本负载平衡的“足够好”的解决方案?

[dns] [load-balancing]中对此有一些讨论标签中,我已经阅读了一些关于这个主题的很棒的帖子。

我知道通过多个循环 A 记录进行 DNS 负载平衡的常见缺点:

  • DNS 记录通常没有心跳或故障检测,因此如果轮换中的给定服务器出现故障,则必须手动从 DNS 条目中删除其 A 记录
  • 必须将生存时间 (TTL) 设置得非常低才能使其正常工作,因为 DNS 条目在整个 Internet 中都被大量缓存
  • 客户端计算机负责查看有多个 A 记录并选择正确的记录

但是,轮询 DNS 作为一个启动器是否足够好,总比没有好,“在我们研究和实施更好的替代方案的同时”为我们的静态内容负载平衡的形式吗?或者 DNS 循环在任何情况下都毫无价值?

Wil*_*eau 59

杰夫,我不同意,负载平衡并不意味着冗余,事实上恰恰相反。您拥有的服务器越多,在给定时刻出现故障的可能性就越大。这就是为什么在做负载均衡时冗余是强制性的,但不幸的是,有很多解决方案只提供负载均衡而不进行任何健康检查,导致服务不太可靠。

通过将负载分布在多个点(可能在地理上分布),DNS 轮循机制非常适合增加容量。但它不提供故障转移。您必须首先描述您试图涵盖的故障类型。必须使用标准 IP 地址接管机制(VRRP、CARP 等)在本地解决服务器故障。服务器上到两个交换机的弹性链路涵盖了交换机故障。WAN 链路故障可以通过您和您的提供商之间的多链路设置来解决,使用路由协议或第 2 层解决方案(例如:多链路 PPP)。BGP 应该涵盖站点故障:您的 IP 地址在多个站点上复制,并且您仅在它们可用的地方将它们通告给网络。

从您的问题来看,您似乎只需要提供服务器故障转移解决方案,这是最简单的解决方案,因为它不涉及任何硬件,也不与任何 ISP 签约。为此,您只需在服务器上设置适当的软件,这是迄今为止最便宜和最可靠的解决方案。

您问“如果 haproxy 机器出现故障怎么办?”。一样的。我认识的所有使用 haproxy 进行负载平衡和高可用性的人都有两台机器,并在它们上运行 ucarp、keepalived 或 heartbeat,以确保其中一台始终可用。

希望这会有所帮助!

  • “无冗余负载平衡”的一个简单示例是 RAID0。 (13认同)
  • 一点也不。如果 DNS 不使用缓存,它会起作用,但事实并非如此,客户端无法强制刷新缓存。与任何经常切换 DNS 条目的人交谈,他们会告诉您,即使他们在 5 分钟内观察到 80% 的切换,但通常需要一周以上的时间才能接近 100%。因此 DNS 不提供故障转移。 (7认同)
  • -1:“不提供故障转移” - 是的,它提供 - 并且它在唯一可以可靠地确定不可用性的地方 - 在客户端实现它。 (2认同)

Sch*_*hof 20

作为负载平衡,它是贫民窟,但或多或​​少有效。如果您有一台服务器从负载中掉下来,并希望将其分散到多台服务器上,那么这可能是一个很好的理由,至少是暂时这样做。

有许多有效的批评将循环 DNS 视为负载“平衡”,除了作为短期创可贴之外,我不建议这样做。

但是你说你的主要动机是避免单服务器依赖。如果没有某种自动方式使死服务器停止轮换,那么作为防止停机的一种方式,它并不是很有价值。(通过自动从轮换中拉出服务器的方式和较短的 TTL,它变成了贫民窟故障转移。手动,甚至不是那样。)

如果您的两个循环服务器中的一个出现故障,那么您 50% 的客户将出现故障。这比仅使用一台服务器的 100% 故障要好,但几乎任何其他进行真正故障转移的解决方案都会比这更好。

如果一台服务器发生故障的概率为 N,则两台服务器发生故障的概率为 2N。如果没有自动、快速的故障转移,此方案会增加您的某些用户遇到故障的可能性。

如果您打算手动使死服务器停止轮换,您将受到执行此操作的速度DNS TTL 的限制。如果服务器在凌晨 4 点死机怎么办?真正故障转移的最佳部分是整夜入睡。 您已经在使用 HAProxy,所以您应该熟悉它。我强烈建议使用它,因为 HAProxy 正是为这种情况而设计的。

  • 完全偏离主题,但我们也有需要多个 HAProxy 实例进行故障转移的问题——如果 HAProxy 机器出现故障怎么办?不过,未来问题的主题对于这个问题来说确实是题外话。 (3认同)
  • +1 - “使用自动化方式......它变成了贫民窟故障转移。手动它甚至不是那样。” 应该是大粗体字母。如果您不监控机器并在它们出现故障时将它们从 DNS 中删除,那么 DNS 循环将成为*责任*,而唯一合理的方法是使用自动化解决方案。有比 DNS 循环法更好的解决方案。 (2认同)

Aln*_*tak 15

我之前已经说过好几次了,我会再说一遍 -如果弹性是问题,那么 DNS 技巧不是答案

最好的 HA 系统将允许您的客户对每个请求继续使用完全相同的 IP 地址。这是确保客户端甚至不会注意到失败的唯一方法。

因此,基本规则是真正的弹性需要 IP路由级别的技巧。使用负载平衡器设备,或 OSPF“等价多路径”,甚至 VRRP。

另一方面,DNS 是一种寻址技术。它的存在仅仅是为了从一个命名空间映射到另一个命名空间。它的设计不允许对该映射进行非常短期的动态更改,因此当您尝试进行此类更改时,许多客户端要么不会注意到它们,要么最多需要很长时间才能注意到它们。

我还要说,既然负载对您来说不是问题,那么您最好准备另一台服务器作为热备用运行。如果您使用愚蠢的轮询,您必须在出现问题时主动更改 DNS 记录,因此您最好主动将热备用服务器启动,而不是更改您的 DNS。


Mic*_*aff 15

循环 DNS 并不是人们认为的那样。作为 DNS 服务器软件(即BIND)的作者,我们让用户想知道为什么他们的循环停止按计划工作。他们不明白,即使 TTL 为 0 秒,也会有一定数量的缓存存在,因为一些缓存无论如何都会放置最短时间(通常为 30-300 秒)。

此外,虽然您的 AUTH 服务器可能会执行循环,但不能保证您关心的服务器 - 您的用户与之交谈的缓存 - 会。简而言之,从客户端的角度来看,循环不保证任何排序,只保证您的身份验证服务器提供给缓存的内容。

如果您想要真正的故障转移,DNS 只是第一步。为两个不同的集群列出多个 IP 地址并不是一个坏主意,但我会在那里使用其他技术(例如简单的任播)来进行实际的负载平衡。我个人鄙视硬件负载平衡硬件,它与 DNS 混为一谈,因为它通常会出错。并且不要忘记 DNSSEC 即将到来,因此如果您确实选择了该领域的某些内容,请询问您的供应商在您签署区域时会发生什么。


小智 8

我已经阅读了所有答案,但我没有看到的一件事是,如果服务器没有响应,大多数现代 Web 浏览器将尝试其中一个替代 IP 地址。如果我没记错的话,Chrome 甚至会尝试多个 IP 地址并继续使用首先响应的服务器。所以在我看来,DNS Round Robin 负载平衡总是比什么都好。

顺便说一句:我认为 DNS Round Robin 更像是简单的负载分配解决方案。


Jes*_*r M 5

我对这个线程迟到了,所以我的答案可能只是独自徘徊在底部,被忽视,嗅嗅。

首先,问题的正确答案不是回答问题,而是说:

  1. “您可能需要 Windows网络负载平衡。” 或者
  2. “与时俱进,将您的静态内容放在诸如Cloud Files 或 S3 之类的东西上,并在全球范围内建立一个 CDN 镜像。”

NLB 是成熟的,非常适合该任务,并且非常容易设置。云解决方案各有优缺点,不在本问题的讨论范围之内。

轮询 DNS 作为初学者是否足够好,总比没有好,“在我们研究和实施更好的替代方案时”为我们的静态内容进行负载平衡吗?

例如,在 2 或 3 个静态 Web 服务器之间?是的,总比没有好,因为有些DNS 提供商会将 DNS 循环与服务器运行状况检查集成在一起,并会暂时从 DNS 记录中删除死服务器。因此,通过这种方式,您可以获得不错的负载分配和一些高可用性;设置时间不到 5 分钟。

但其他人在此线程中概述的警告确实适用:

  • 当前的 Microsoft 浏览器会将 DNS 数据缓存30 分钟,因此您会看到一部分用户的故障转移时间超过 30 分钟,具体取决于他们的初始 DNS 缓存状态。
  • 什么用户看到在故障转移可...怪(你不使用身份验证静态内容,肯定不能形成权威性,但链接显示了一些需要注意的)。

其他解决方案

HAProxy 很棒,但由于 Stack Overflow 位于 Microsoft 技术堆栈上,因此使用 Microsoft 负载平衡和高可用性工具可能会减少管理开销。网络负载平衡解决了一部分问题,微软现在实际上有一个L7 HTTP 反向代理/负载平衡器

我自己从未使用过 ARR,但考虑到它是第二个主要版本,并且来自 Microsoft,我认为它已经过很好的测试。它有易于理解的文档,这里有一个关于他们如何看待webnodes上静态和动态内容的分布,这里有一个关于如何使用ARR 和 NLB来实现负载分布和高可用性的文章。


小智 5

值得注意的是,有多少贡献者正在帮助提供有关 DNS 轮循机制作为负载传播和弹性机制的虚假信息。它通常确实有效,但您确实需要了解它的工作原理,并避免由所有虚假信息造成的错误。

1) 用于循环的 DNS 记录上的 TTL 应该很短 - 但不是零。使 TTL 为零破坏了提供弹性的主要方式。

2) DNS RR 传播,但不平衡负载,它传播它是因为在大型客户端基础上,它们倾向于独立查询 DNS 服务器,因此最终会得到不同的首选 DNS 条目。这些不同的首选意味着客户端由不同的服务器提供服务,并且负载是分散的。但这一切都取决于哪个设备正在执行 DNS 查询,以及它保存结果的时间。一个常见的例子是公司代理(为它们执行 DNS 查询)背后的所有客户端最终都将定位到单个服务器。负载是分散的 - 但它不是均匀平衡的。

3) DNS RR 提供弹性,只要客户端软件正确实现它(TTL 和用户注意力都不会太短)。这是因为 DNS 循环提供了服务器 IP 地址的有序列表,客户端软件应尝试依次联系每个人,直到找到接受连接的服务器。

因此,如果首选服务器关闭,则客户端 TCP/IP 连接超时,并且提供 TTL 或注意力跨度均未过期,则客户端软件会再次尝试连接到列表中的第二个条目 - 依此类推,直到TTL 过期,或者它到达列表的末尾(或者用户厌恶地放弃)。

一长串损坏的服务器(你的错)和大的 TCP/IP 连接重试限制(客户端配置错误)可能会导致客户端真正找到工作服务器之前很长一段时间。太短的 TTL 意味着它永远不会工作到列表的末尾,而是发出一个新的 DNS 查询并获得一个新的列表(希望以不同的顺序)。

有时客户端不走运,新列表仍然以损坏的服务器开始。为了给系统提供客户端弹性的最佳机会,您应该确保 TTL 比典型的注意力持续时间长,并且让客户端到达列表的底部。

一旦客户端找到一个工作服务器,它应该记住它,当它需要建立下一个连接时,它不应该重复搜索(除非 TTL 已过期)。较长的 TTL 减少了用户在客户端搜索工作服务器时遇到延迟的频率 - 提供更好的体验。

4) DNS TTL 自成一体,当您想手动更改 DNS 记录(例如,删除长期损坏的服务器)时,短 TTL 允许该更改快速传播(一旦您有时间去做),所以考虑在您知道问题之前需要多长时间并进行手动更改之间的平衡 - 以及普通客户端只需在 TTL 到期时重新搜索工作服务器的事实。

DNS 轮询有两个突出的特点,使其在广泛的场景中非常具有成本效益 - 首先是免费的,其次它几乎与您的客户群在地理上一样分散。

它不会引入所有其他“聪明”系统所做的新“故障单元”。没有添加的组件可能会在整个相互链接的元素负载上经历共同和同时发生的故障。

“聪明”的系统很棒,并引入了美妙的机制来协调和提供无缝平衡和故障转移机制,但最终,它们用来提供无缝体验的方法是它们的致命弱点——额外的复杂的事情可能会出错,当它发生时,将提供系统范围内的无缝故障体验。

所以是的,DNS 循环对于您超越将所有静态内容托管在一个地方的单个服务器来说绝对是“足够好”的第一步。