一个请求的旅程:数据中心网络全景

Mont Sainte-Victoire and the Viaduct of the Arc River Valley, Paul Cézanne, 1882-85
Paul Cézanne,《圣维克多山与弧形河谷高架桥》, 1882-85 — 高架桥连接两岸,如同骨干网连接数据中心。基础设施的美在于它消失在风景中,却支撑着一切
这篇文章的价值:大多数后端工程师知道请求从浏览器发出、到服务器处理、再返回响应。但中间经过了什么?PoP 节点、骨干网光纤、Clos 交换矩阵、eBPF 四层负载均衡、VXLAN 容器网络——这些基础设施决定了你的系统能做到什么、不能做到什么。这篇文章追踪一个请求从用户手机到数据中心服务器的完整旅程,沿途拆解每一层的关键技术。

全局视角:三层架构

任何大规模互联网公司的网络基础设施都是三层结构:

职责例子
Edge / PoP用户流量入口,TLS 终止,地理路由东京 PoP 接收日本用户的请求
Backbone数据中心之间的高速私有光纤,运行 SR/MPLS新加坡 DC ↔ 美国 DC,~120ms RTT
DC InternalClos 交换矩阵连接 DC 内所有服务器Leaf-Spine-Core 三层交换

一个东京用户打开某个 App:手机 DNS 解析到最近的东京 PoP IP → PoP 终止 TLS,静态内容直接从 CDN 返回 → 动态请求走骨干网(SR/MPLS)到新加坡 DC → 进入 DC 后经过 Katran(L4 LB)→ Proxygen(L7 LB)→ 应用服务器 → 如果需要美国 DC 的数据,再走一次跨洋骨干网 → 响应通过 DSR 直接返回用户,绕过 L4 LB。

接下来沿着这条路径,逐层拆解。

DC 内部:Clos 架构

一台大型交换机无法扩展到数十万台服务器。Clos 拓扑用大量便宜的小交换机组合成一个无阻塞、可水平扩展的网络。

三层结构

                      ┌─────────┐   ┌─────────┐
                      │  Core 1 │   │  Core 2 │        ← Layer 3: 连接 Pod
                      └────┬┬───┘   └───┬┬────┘
                     ╱╱    ││    ╲╲    ╱╱││
            ┌───────╱╱─────┘│     ╲╲─╱╱──┘│
            │      ╱╱       │      ╲╱╱    │
     ┌──────┼────╱╱─────────┼──────╱╲─────┼──────────┐
     │ Pod A│   ╱╱          │     ╱╱ ╲╲   │    Pod B  │
     │      ▼  ▼            ▼    ▼     ▼  ▼           │
     │  ┌────────┐     ┌────────┐  ┌────────┐  ┌────────┐
     │  │Spine 1 │     │Spine 2 │  │Spine 3 │  │Spine 4 │ ← Layer 2
     │  └┬──┬──┬─┘     └┬──┬──┬─┘  └┬──┬──┬─┘  └┬──┬──┬─┘
     │   │  │  │         │  │  │     │  │  │      │  │  │
     │   ▼  ▼  ▼         ▼  ▼  ▼     ▼  ▼  ▼      ▼  ▼  ▼
     │ ┌──┐┌──┐┌──┐   ┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐
     │ │L1││L2││L3│   │L1││L2││L3│ │L1││L2││L3│ │L1││L2││L3│ ← Layer 1: Leaf (ToR)
     │ └┬─┘└┬─┘└┬─┘   └┬─┘└┬─┘└┬─┘ └┬─┘└┬─┘└┬─┘ └┬─┘└┬─┘└┬─┘
     │  │   │   │       │   │   │     │   │   │     │   │   │
     │ ▓▓▓ ▓▓▓ ▓▓▓   ▓▓▓ ▓▓▓ ▓▓▓  ▓▓▓ ▓▓▓ ▓▓▓  ▓▓▓ ▓▓▓ ▓▓▓  ← 服务器机架
     └────────────────────────────┘  └────────────────────────┘
名称职责
Layer 1Leaf (ToR)机架顶部交换机,直连服务器。每个机架一台
Layer 2Spine连接同一 Pod 内所有 Leaf,全网状连接
Layer 3Core连接不同 Pod,跨 Pod 流量经过 Core

流量路径的跳数:

Pod:可重复的构建单元

Pod 是一组 Leaf + 对应的 Spine,是 DC 扩展的基本单位。要扩容?加一个 Pod,连到 Core 就行。

用 64 端口交换机算一下规模:

Leaf:32 端口朝下连服务器 → 每机架 32 台服务器
Pod: 32 个 Leaf              → 32 × 32 = 1,024 台服务器
DC:  32 个 Pod               → 32 × 1,024 = 32,768 台服务器

需要更多?加一层(5-stage Clos / Super Spine),可以支撑数十万台服务器。大型互联网公司的 F16 Fabric 就是这种多级 Clos 设计。

ECMP:等价多路径

Clos 架构的核心设计原则。当 Leaf 1 发包到 Leaf 4,有多条等价路径经过不同的 Spine。交换机对五元组(源 IP、目的 IP、源端口、目的端口、协议)做哈希,均匀分发到所有路径。

  Leaf 1 ──发包──►  要到 Leaf 4,有 4 条等价路径:

  Leaf 1 ─── Spine A ─── Leaf 4    ← hash(五元组) = 0
  Leaf 1 ─── Spine B ─── Leaf 4    ← hash(五元组) = 1
  Leaf 1 ─── Spine C ─── Leaf 4    ← hash(五元组) = 2
  Leaf 1 ─── Spine D ─── Leaf 4    ← hash(五元组) = 3

  流量均匀分散 → 无瓶颈 → Spine 挂一台自动重分布

ECMP 的意义:

Oversubscription:超卖比

Leaf 交换机的下行带宽(面向服务器)和上行带宽(面向 Spine)的比值。

比例含义场景
1:1无阻塞,所有服务器可以同时全速通信延迟敏感(DB 集群、ML 训练)
3:1只有 1/3 的服务器带宽可以同时上行通用计算(统计上够用)
4:1+更高超卖,便宜但有风险冷存储、批处理

实际影响:设计服务时,把频繁通信的服务放在同一个机架或 Pod 里,避免超卖瓶颈。这就是为什么 HDFS 把一个副本放在同机架、另一个放在跨机架。

骨干网:Segment Routing

数据中心之间通过私有骨干网连接。传统 MPLS 需要每个中间路由器维护转发状态(通过 LDP/RSVP)。Segment Routing(SR)是它的进化:把完整路径编码在包头里,中间路由器只需要读取下一条指令。

MPLS 类比:坐出租车,每个路口都要问路
SR 类比:  出发前拿到完整 GPS 导航,每个路口只看下一步指令
  MPLS:每个路由器都要维护转发状态
  ┌───┐    ┌───┐    ┌───┐    ┌───┐
  │ A │───►│ B │───►│ C │───►│ D │     B,C 各自查 LDP 表决定下一跳
  └───┘    └───┘    └───┘    └───┘

  SR:路径编码在包头,中间路由器只执行指令
  ┌───┐    ┌───┐    ┌───┐    ┌───┐
  │ A │───►│ B │───►│ C │───►│ D │
  └───┘    └───┘    └───┘    └───┘
  包头: [B, C, D]   [C, D]    [D]       每一跳弹出一个 SID

两种 Segment ID:

SRv6 是各大超大规模数据中心在推的方向。128 位的 SID 可以同时编码目的地和操作(比如"解封装"、"查 VPN 表"),比 SR-MPLS 的 20 位标签灵活得多。

负载均衡:L4 + L7 两层

数据中心里有两种本质不同的"负载均衡"协同工作。很多人把它们混为一谈,但它们解决的问题完全不同:

ECMP(网络层)应用负载均衡器
回答的问题这个包走哪条物理路径?这个请求由哪台服务器处理?
决策依据五元组哈希健康检查、负载、Session、URL、Header
应用感知完全感知
所在层L3/L4(交换机)L4/L7(软件)

Katran:基于 eBPF 的 L4 负载均衡器

Katran 不是一个独立设备——它是一个 eBPF/XDP 程序,直接跑在每台 L7 LB 服务器的网卡上。

                         用户请求
                            │
                            ▼
                    ┌───────────────┐
                    │  DC Border    │
                    │  Router       │
                    └──┬─────┬────┬─┘
                       │     │    │      ← ECMP + Anycast
                       ▼     ▼    ▼
                 ┌──────┐ ┌──────┐ ┌──────┐
                 │Server│ │Server│ │Server│   每台都跑 Katran
                 │  A   │ │  B   │ │  C   │
                 └──┬───┘ └──┬───┘ └──┬───┘
        ┌───────────┤        │        │
        │           │        │        │
        ▼           ▼        ▼        ▼
   ┌─────────┐ ┌─────────────────────────────┐
   │本机处理  │ │  封装转发到其他后端服务器      │
   │Proxygen │ │                              │
   │ (L7 LB) │ │  ┌──────┐┌──────┐┌──────┐   │
   └─────────┘ │  │App 1 ││App 2 ││App 3 │   │
               │  └──┬───┘└──┬───┘└──┬───┘   │
               └─────┼───────┼───────┼────────┘
                     │       │       │
                     └───────┼───────┘
                             │
                             ▼
                    DSR:响应直接回用户
                    (绕过 Katran)

三个关键设计决策:

硬件 LB (F5)LVS/IPVSKatran (eBPF)
性能高但有上限中高数百万 PPS
成本$100K+ / 台免费免费
单点故障看部署方式否(每台服务器都跑)
扩展方式买更多设备加服务器加服务器

Overlay 网络:容器怎么通信

你的代码跑在容器里,容器有虚拟 IP,物理网络不认识这些 IP。Overlay 网络桥接这个鸿沟。

Underlay vs Overlay

是什么IP设备
UnderlayClos 物理交换矩阵192.168.x.x(宿主机 IP)Leaf, Spine, Core
Overlay容器虚拟网络10.244.x.x(Pod IP)veth, bridge, VXLAN

Linux 虚拟网络设备

一个包的完整旅程:跨主机容器通信

  Host 1 (192.168.1.10)                          Host 2 (192.168.2.20)
 ┌──────────────────────────┐                   ┌──────────────────────────┐
 │                          │                   │                          │
 │  ┌──────────────────┐    │                   │    ┌──────────────────┐  │
 │  │ Container A       │    │                   │    │ Container B       │  │
 │  │ IP: 10.244.1.5    │    │                   │    │ IP: 10.244.3.8    │  │
 │  │      │ eth0        │    │                   │    │       eth0 │      │  │
 │  └──────┼─────────────┘    │                   │    └────────────┼──────┘  │
 │         │ veth pair        │                   │       veth pair │         │
 │         ▼                  │                   │                 ▼         │
 │  ┌─────────────┐          │                   │          ┌─────────────┐  │
 │  │   Bridge     │          │                   │          │   Bridge     │  │
 │  │  (cni0)      │          │                   │          │  (cni0)      │  │
 │  └──────┬──────┘          │                   │          └──────┬──────┘  │
 │         │ 目的地不在本机   │                   │      解封装后转发│         │
 │         ▼                  │                   │                 ▲         │
 │  ┌─────────────┐          │                   │          ┌─────────────┐  │
 │  │ VXLAN (VTEP)│          │                   │          │ VXLAN (VTEP)│  │
 │  │ 封装 UDP:4789│          │                   │          │ 解封装       │  │
 │  └──────┬──────┘          │                   │          └──────┬──────┘  │
 │         │                  │                   │                 ▲         │
 │         ▼                  │                   │                 │         │
 │  ┌─────────────┐          │                   │          ┌─────────────┐  │
 │  │  物理网卡    │           │                   │          │  物理网卡    │  │
 │  └──────┬──────┘          │                   │          └──────┬──────┘  │
 └─────────┼──────────────────┘                   └──────────────────┼────────┘
            │                                                       ▲
            │            Clos 物理网络                               │
            │     ┌──────────────────────────┐                      │
            └────►│  Leaf → Spine → Leaf     │──────────────────────┘
                  │  (ECMP 基于外层 IP 路由)  │
                  └──────────────────────────┘

为什么用 VXLAN 而不是 VLAN?VLAN 只支持 4,096 个 ID(12 位)。VXLAN 用 24 位 VNI,支持 1600 万个虚拟网络——多租户 DC 环境必需的。

K8s CNI 插件对比

CNI方式性能复杂度
Flannel (VXLAN)VXLAN 封装好(有封装开销)简单
Calico (IPIP)IP-in-IP 封装更好(更轻的封装)中等
Calico (BGP)直接路由,无封装最好(原生路由)需要支持 BGP 的交换机
Cilium (eBPF)eBPF,绕过 bridge/iptables优秀中等

超大规模数据中心大概率用的是类似 Calico BGP 的直接路由方案——物理交换机知道容器子网的路由,不需要封装,性能最好,但需要网络基础设施的深度集成。

DC 内部 vs 公网:两个完全不同的世界

这是最反直觉的部分。教科书上的 TCP/IP 是为公网设计的——高延迟、高丢包、未知带宽。DC 内部是一个完全不同的环境,需要在每一层做不同的优化。

属性公网DC 内部
RTT10-200ms10-100μs(低 1000 倍)
丢包率1-5%<0.001%
带宽未知、可变已知(25G/100G/400G)
跳数10-202-4
信任不可信完全可控

传输层的差异

公网做法DC 做法为什么
TCP:丢包就砍半窗口DCTCP:基于 ECN 的细粒度速率调整丢包信号太粗暴;ECN 提供早期、按比例的拥塞反馈
每个请求建 TCP 连接连接池 + gRPC/HTTP2 多路复用百万级服务间调用,握手开销不可接受
什么都用 TCPML 训练用 RDMA/RoCEGPU 梯度交换需要 <2μs 延迟,绕过 CPU

内核绕过技术

内核网络栈通过上下文切换和协议处理增加延迟。DC 工作负载直接绕过它:

技术原理用途
DPDK用户态包处理,完全绕过内核高性能 LB、NFV
RDMA/RoCE网卡直接读写远端内存,CPU 不参与GPU 训练、分布式存储
XDP/eBPF在网卡驱动层拦截包(内核最早的 hook 点)Katran LB、Cilium
io_uring异步 I/O,减少系统调用开销高性能存储引擎

Incast:DC 特有的拥塞模式

一个请求扇出到 N 台服务器(比如分布式查询),N 台同时响应,瞬间压垮请求方 Leaf 交换机的缓冲区。结果:丢包、TCP 重传、延迟飙升。

解法:

完整的请求路径

现在把所有层串起来:

  ┌──────────┐
  │ 用户手机  │  东京
  │          │
  └────┬─────┘
       │ DNS → Anycast IP
       ▼
  ┌──────────┐
  │ PoP 东京  │  TLS 终止
  │          │  静态内容 → CDN 直接返回
  └────┬─────┘
       │ 动态请求
       ▼
  ═══════════════════════  骨干网 (SR/MPLS, 私有光纤, ~120ms)
       │
       ▼
  ┌──────────────────────────────────────────────────────┐
  │ 新加坡 DC                                            │
  │                                                      │
  │  ┌──────────────┐                                    │
  │  │ Border Router │  ECMP + Anycast                   │
  │  └──────┬───────┘                                    │
  │         ▼                                            │
  │  ┌──────────────┐                                    │
  │  │ Katran        │  L4 LB (XDP/eBPF)                │
  │  │ 一致性哈希     │                                   │
  │  └──────┬───────┘                                    │
  │         ▼                                            │
  │  ┌──────────────┐                                    │
  │  │ Proxygen      │  L7 LB (TLS, URL路由, 健康检查)   │
  │  └──────┬───────┘                                    │
  │         ▼                                            │
  │  ┌──────────────┐       ┌──────────────┐             │
  │  │ App Server   │──────►│ 其他服务      │             │
  │  │ (容器)        │ VXLAN │ (跨Pod/跨主机) │             │
  │  └──────┬───────┘       └──────────────┘             │
  │         │                                            │
  └─────────┼────────────────────────────────────────────┘
            │
            │ DSR:响应直接返回用户,绕过 Katran
            ▼
  ┌──────────┐
  │ 用户手机  │
  └──────────┘

从用户发出请求到收到响应,经过了 DNS、CDN、PoP、骨干网、边界路由、ECMP、eBPF 四层 LB、七层 LB、容器 overlay 网络——每一层都在解决一个特定的问题,每一层的设计都受限于物理定律(光速、带宽、缓冲区大小)。

总结

几个值得记住的关键直觉: