TCP 是有状态的,应要求后续数据包到达同一服务器。(无状态)HTTP 在 TCP 之上运行,CDN 可以使用任播。
那么 TCP 如何与任播配合使用?如果 syn 和 ack 发送到不同的服务器怎么办?我想我听说 Google 对此有一些解决方案,但我不确定。
如果有区别,请回答 IPv4 和 IPv6。
答案1
这是众多挑战之一,可以通过多种不同方式解决。最简单的方法是忽略它并希望获得最好的结果。只要路由在连接中途不发生变化,就没问题。但是当路由确实发生变化时,它将破坏所有受路由更改影响的连接。其他答案已经对这种方法进行了更深入的探讨。
另一种方法是跟踪连接路由到的位置。如果数据包被路由到错误的 POP,CDN 可以将数据包通过隧道传输到正确的 POP 进行进一步处理。这确实会带来额外的开销,一旦发生这种情况,客户端将体验到更长的延迟。这种延迟将持续整个连接的生命周期。但对于用户体验来说,这可能比断开的连接更好。
就带宽消耗而言,开销并不是很大,因为它只影响一个方向的数据包,而且这个方向往往是带宽使用量最小的方向。
跟踪可以在连接级别进行,也可以通过跟踪哪个是服务于每个客户端 IP 地址的首选 POP 来进行。用于跟踪连接的最明显的数据结构是分布式哈希表。
如果客户端支持 MPTCP,则可以使用另一种解决方案。一旦建立连接,服务器将使用单播 IP 地址打开另一个子流。如果成功建立了这样的子流,则只需在连接的剩余生命周期内使用单播地址,连接就可以在任播地址的路由更改后继续存在。
原则上,上述所有方法对于 IPv4 和 IPv6 都是相同的。但在实践中,由于 IP 地址短缺,某些解决方案在 IPv4 上可能效果不佳。
例如,MPTCP 方法确实要求每台服务器都有一个公共 IP 地址才能正常工作。大型负载平衡设置可能有太多服务器,无法为每个服务器分配一个公共 IP 地址。此外,如果客户端位于 NAT 后面(IPv4 中经常出现这种情况),则服务器无法启动新子流的建立。这意味着服务器必须将单播 IP 地址作为初始子流上的选项发送,并让客户端启动额外的子流。
我不知道CDN使用了上述哪种方法。
答案2
任播最好被描述为“一对最近”的路由方案,并且通常通过让 BGP(边界网关协议)宣布来自多个来源的目标 IP 来工作,从而将数据包路由到列出的最近的目标 IP。
因此,从广义上讲,任播只是用来确定要连接哪个服务器,并没有什么使其不适合 TCP 或有状态网络的原因。
任播的主要用例是 CDN(内容分发网络),它通常具有短暂和/或无状态的连接 - 正如您在分发大量小型静态网页内容时所期望的那样。在此用例中,任播假设网络拓扑至少在会话期间保持不变,这是一个相当安全的假设,因为典型会话的长度较短,并且该假设不成立的后果最小 - 最坏的情况是会话在中间失败,用户重新加载网页。
对于较长的会话或无法容忍中断的用途,使用任播的缺点是网络拓扑更有可能在较长的时间段内发生变化,并且如果发生这种情况,连接将悄无声息地中断。(弹出切换。)正如您在问题中提到的,Google(和其他公司)正在研究解决此问题的专有方法,但目前,所有这些都是专有和秘密的。
因此,对于任播如何与 TCP 协同工作的这个问题,答案实际上是它可以正常工作,除非网络拓扑发生变化......如果拓扑发生变化,它 [可能] 就会中断。
有这里有一个有趣的演示(警告,pdf)使用有关使用任播的真实世界数据,包括一些长寿命会话,并且似乎在现实世界中,“弹出切换”(网络拓扑在会话中间发生变化并断开连接)是一种非常不常见的体验 - 在一个数据集中,有 683,204 个会话,以及 23,795 个超过 10 分钟的会话,只有 4 个会话发生了弹出切换。
答案3
它的效果比您预期的要好,特别是对于通常很短暂的 TCP 会话(例如由 HTTP 客户端生成的会话)。
任播假设网络拓扑在会话期间不会发生变化,即使发生变化,另一个端点也不可能突然比协商会话的端点更近。应用协议应该处理这种断开/重新连接活动。
CDN 在 Anycast 上表现非常好,因为它们的整个业务模型是短暂的 TCP 会话,具有明显的单向网络传输出去他们的网络。如果 ACK 流最终流向其最初协商的端点以外的某个地方,则该资产的连接将挂起。