通过共置 (Colocation) 降低延迟
2026年8月27日
在前两个章节中,《Latency》一书从延迟是什么,到如何测量延迟,概览式地介绍了延迟。从这个章节开始,作者把焦点转向如何优化延迟;而在这个章节中,作者会从“共置 colocation”的角度来谈如何优化。
什么是共置?为何对延迟有帮助?
想象一下,假如今天有个网页应用程序,客户端在亚洲,而服务器在美洲,服务器背后调用的数据库又在欧洲;当用户做某个操作时,客户端发送的请求要先走一万公里到服务器端,服务器的请求往返数据库要各走五千公里,最后服务器端返回给客户端要再走一万公里。
因为数据传输需要时间,即使用光纤网络,上面这些多走的距离,至少会增加 150 毫秒的延迟(还不算上海底电缆通常不是直线距离,而是会弯曲绕路)。但如果今天把服务器与数据库都放在亚洲,甚至在亚洲当中,把服务器与数据库都放在跟客户端同一个区域,就能因为少走的这些距离,让服务器与数据库之间的网络延迟有机会压到 10 毫秒以下;如果连应用程序本身也部署得更靠近用户,完整请求的网络延迟还能进一步下降。
换句话说,仅仅是把不同机器的物理位置放近,就能够大幅降低延迟。而这种把组件放得靠近一点的方式,就是共置。之所以要共置,是因为当系统分散于不同节点时,节点之间的通信延迟可以通过拉近距离而降低。
事实上,共置的概念不仅局限于不同机器之间,在单一机器的内部,同样可以通过共置来降低延迟。作者举了 CPU 为例,在同一台机器当中,数据离 CPU 有多远,也会影响延迟。以 CPU 缓存来说,如果数据在缓存中,CPU 可以很快取得(10 纳秒内);但假如不在缓存中,CPU 必须去 DRAM 主内存读取,就得花比较多时间(100 纳秒左右),两者在延迟上的差距可能高达十倍。
以边缘计算为例
在实务上提到共置,相信多数人会想到边缘计算 (edge computing) 这个概念。边缘计算是很典型地把计算与数据一同移到更靠近终端用户的方式,借此降低延迟。边缘计算通过缩短节点之间的距离,能协助降低通信造成的延迟。
这类延迟主要可以分成两种,一种是地理延迟 (geographical latency),另一种被称为最后一英里延迟 (last-mile latency)。
地理延迟是指两个节点之间的地理距离会带来延迟,也就是上面提到的,从亚洲发送请求到美洲,以及从美洲返回数据到亚洲这种往返所导致的延迟。要降低地理延迟,除了上面提到的把服务器与数据库放在同一个地方外,把两者都放在与终端用户比较近的区域,也是一种能降低延迟的手段。这种把服务器端部署得更靠近客户端的做法,也是共置的一种体现。
在实务上要做到这一点,CDN (content delivery network,内容分发网络) 是最广泛使用的手段。CDN 把服务器部署在全球各地的数据中心中,当开发者把网页经常访问的脚本、图片、影片放在 CDN 节点中,能确保这些内容在物理距离上更靠近客户端,借此降低数据传输所需的时间。我们先前在 系统设计必备知识点 — CDN (Content Delivery Network)? 一文中更详细地介绍过 CDN 的相关概念,推荐读者回顾。
最后一英里延迟则是网络数据包从最近的骨干网络到设备之间的延迟。如果从距离来看,这段延迟理论上应该不到 1 毫秒,然而因为各种因素,最后一英里的延迟可能达到数十毫秒,因此也不容忽视。
节点内部延迟 (Intranode Latency)
前一段落谈到的延迟属于节点之间的延迟 (internode latency),意即延迟的主要来源是分布式系统中不同节点之间的通信。除了节点之间的延迟,节点内部延迟 (intranode latency) 是指单一节点内部各种延迟造成的影响,包含软件栈与硬件架构,也能够通过共置来加速。
当两台机器通过网络通信时,中间会经过一层又一层的抽象,每一层抽象中都有不同的协议负责处理,借此规范数据如何被发送与接收。举例来说,前后端工程师熟悉的 TCP/IP 与 HTTP 就属于不同层级的协议。
当客户端发送 HTTP 请求后,应用层的数据会交给 TCP,再封装进 IP 数据包;如果底层使用以太网,还会进一步封装成以太网帧。在这些不同层级中,也不只有一种协议可以选择。对应用程序来说,除了 TCP 也可以选择 UDP。
相比 TCP,UDP 更适合数据中心内部的低延迟网络。虽然延迟比较低,但因为协议本身属于不可靠通信,如果某个路由器丢弃了包含 UDP 数据报的网络数据包,网络栈不会尝试重新发送。如果是在传输上相对不可靠的公共网络,则需要确保应用层能够容忍数据丢失,否则 UDP 可能不是好的选择。
相比之下,TCP 提供可靠且有序的传输机制,遇到数据丢失时会进行重传。但这也意味着对于许多延迟敏感的应用程序来说,TCP 可能不是最佳选择。因此,业界现在有不少方案(例如 Aeron)尝试在 UDP 上建立可靠性,在维持 UDP 低延迟的同时,提供接近 TCP 的可靠性。
进一步来说,上面提到的这些流程,即使是同一台机器中的不同进程 (process) 相互通信,仍会经过其中一部分。例如,即使服务器与数据库位于同一台机器,只要它们分属不同的进程,彼此仍需要通过进程间通信机制交换数据。以通过 TCP 连接本机 PostgreSQL 为例,数据仍会经过操作系统的 TCP/IP 网络栈,因此会让延迟高一些。
加入 E+ 会员方案
如果你觉得这篇分享有帮助,想阅读更深入的内容,欢迎加入 E+ 会员。除了有会员专属的深度文与影片,探讨前后端开发、AI 工程、职业发展,同时有 Discord 社群一同交流与成长。
许多 E+ 会员通过所任职公司的教育训练补助 (E+ 会开立有统编的发票),不用花自己的钱,也能每周通过深度主题文与社群交流,拓展技术视野、加速职业成长。