将一个功能置于一个复杂系统的何处是系统设计中处处遇到的问题。
现在我们都知道传输协议的端到端原则,但在它成为原则之前只是一个观点,曾经有场辩论,有人认为传输协议应该由参与通信的每一跳协同实现,可为什么与此相对的端到端的观点会胜出?核心的点非常现实且容易理解:
- 早期 ARPAnet 要利用现有网络(比如电话网),因此不能对已有网络的 feature(比如可靠性) 做任何假设,只能在上层隔离实现网络无关的协议特性以支持对网络不同需求的应用,但网络并不知道所有应用对网络的期望。
- 这导致了 IP 的分离以及 UDP 的构建,因为并不总能预期应用需要可靠的网络,因此需要一个与可靠协议并列的不可靠协议。现在我们知道分层和模块化是影响性能的关键(来自 RFC817 的预见)。
- 若在网络路由器中支持传输协议,需要采集并保持每条流(or per-packet)状态,为保证状态不丢失,需将其分布式备份,而分布式一致性算法难以构建。反之,仅在通信的主机两端维护这些信息便轻易实现了 “命运共担”。
- 事后我们知道这个基本点带来的 “巨大正向副作用”,网络的无状态性使主机接入变得异常简单,互联网进而蓬勃发展。而随着计算机工业持续发展,主机端实现复杂传输协议并非难事。这极大解放了网络路由器的算法复杂性和性能,否则随主机应用的接入,路由器复杂性将指数级增长,总有一天不堪重负而垮掉;
- 如果协议要满足应用的需求,网络自然没有主机更接近从而更了解应用,网络自然没有主机知道如何更能满足应用,换句话说,让最懂的去做,做不好就不做。
- 这个观点在关注传输性能优化的今天似乎反了过来,网络似乎更懂传输性能的指标和细节,哪里会丢包,哪里在排队,哪里带宽空闲,也已经有了关于跨层优化的大量研究,在细腰模型的约束下,这些研究基本都集中在 “信息如何 report 给传输层” 方面。
- 网络要保持健壮就要保持简单。如果地图丢了怎么办?最简单的假设是没有地图,靠打听问路到达目的地。要假设被问方只具备最少知识,而最少知识就是邻居,即下一跳。这意味着描述要简单。
- 这便是经典的 “IP 逐跳路由”。这意味着所有与逐跳路由无关的信息都不会被保存在路由器上。和上述第二个观点一致,这保证了网络可靠性,但使主机软件变得复杂,考虑到上述第二个观点相同的原因,计算机工业以及软件技术的发展抵消了人们对主机软件复杂性的恐惧。
事后看来,端到端原则让互联网获得巨大成功,但端网分离的端到端原则并不总正确。从互联网破晓到爆发式发展时期,TCP/IP 细腰模型让网络有能力迅速扩展,但扩展到全球近饱和后,管理和性能问题逐渐被关注。当 IoT 终端也实现标准接口时,互联网接入开始从买方市场进入卖方市场。
结构决定行为,存量决定结构。早期的对等通信网络结构早已被分发网络颠覆,看看如今的互联网,作为客户端几乎都在 NAT 后,而早期自然的对等通信是不受待见(抢带宽?)甚至非法(比如 P2P)的,即使 P2P 对等网络,绝大多数情况下,其目的竟然也是获取内容而不是通信,这是多么讽刺。
因此,在历史上有过争议的观点双方需要被重新评估。
或许可以通过构建 overlay 网络的方式来支持当时相反的观点,而不是重构整个互联网(这是不可能的)。比如 CDN,PCDN 就很像 TCP/IP-based NDN,自然可将 CDN 多级 cache 节点当作内容 “路由器”,虽然俺这种理解,仍然无助于解决最后一公里拥塞问题。
浙江温州皮鞋湿,下雨进水不会胖。