最高效的传输需要网络无差别对待数据,保持高熵,分离业务流(stream)和网络流(flow)就是要彻底用网络包消除网络流。
看到一些很卷的做法,都在出各自炫技的方案试图优化大象流,老鼠流,突发流,然后声称自己的算法获得了多么好的效果。
可是交换机(一般意义上的转发设备)根本就不该认识流(flow),而只认识数据包(packet),这是互联网之成互联网的根基:
- 尽力而为;
- 统计复用;
- 去中心化。
流抽象由于下列事实被显化:
- 端到端 TCP 将按序业务流(stream)直接映射到了 IP(flow),在协议层面不支持乱序传输;
- 最短路径优先路由算法强化了 TCP 按序数据流,支撑甚至确保了保序传输。
然而流抽象的显化只是互联网的底层逻辑,数据中心则是另一番景象。
数据中心除了满足 CAP 定理与互联网类似之外,它本质上就是一块大主版。流行的规则架构(如 Spine-Leaf 架构)让 ECMP 变得更普遍,这让最短路径成了路由约束而不是结果,数据应通过所有等价路径到达目标。很明显,若高效利用资源,只需要做一件事,即在传输层面消除流抽象,让所有数据包通过所有等价路径。
因此,所有业务流量被平滑到所有等价路径,拥塞自然缓解,当业务突发很大时,没有任何路径比其它等价路径承载更多负载,也没有任何路径欠载,只要系统总负载没有超载,拥塞甚至被消除。
业务流量突发和链路流量突发因此而分离。
反之,更优的大象流算法则本末倒置,就像在墙面贴画 patch 上打 patch 试图贴牢更靠,只是增加自重让它离坠落更进一步,这种做法是问题的原因,而不是解决方案。正确做法仅仅是让大象流消失。这一点请参考 AWS SRD。
在实践中,只需要:
- 做一个消除流抽象的传输协议(比如 SRD 那般在 receiver 重排序);
- 在交换机上实施基于 packet 而不是基于 flow 的 ECMP 负载均衡。
下面我简单证明这样做的正确性。
解除 M/M/1 模型的泊松到达假设,考虑更实际意义上任意分布到达 G/G/1 模型,平均排队时间 W q W_q Wq 可通过 Kingman 公式近似:
W q ≈ ρ 1 − ρ ⋅ σ a 2 + σ s 2 2 ⋅ 1 μ W_q\approx\dfrac{\rho}{1-\rho}\cdot\dfrac{\sigma_a^2+\sigma_s^2}{2}\cdot\dfrac{1}{\mu} Wq≈1−ρρ⋅2σa2+σs2⋅μ1
其中:
- λ \lambda λ 是到达率, μ \mu μ 是服务率;
- σ a \sigma_a σa 是到达过程的变异系数,由标准差和期望相除度量;
- σ s \sigma_s σs 是服务过程的变异系数,由标准差和期望相除度量;
- ρ = λ μ \rho=\dfrac{\lambda}{\mu} ρ=μλ 是系统利用率。
由 Little 定律容易导出队列长度:
L q = λ ⋅ W q = ρ 2 1 − ρ ⋅ σ a 2 + σ s 2 2 L_q=\lambda\cdot W_q=\dfrac{\rho^2}{1-\rho}\cdot\dfrac{\sigma_a^2+\sigma_s^2}{2} Lq=λ⋅Wq=1−ρρ2⋅2σa2+σs2
而队列长度的方差可由 M/G/1 模型 Pollaczek-Khinchine 公式推广到 G/G/1 模型近似:
V a r ( L q ) = ρ 2 ( 1 − ρ ) 2 ⋅ σ a 2 + σ s 2 2 + ρ \mathrm{Var}(L_q)=\dfrac{\rho^2}{(1-\rho)^2}\cdot\dfrac{\sigma_a^2+\sigma_s^2}{2}+\rho Var(Lq)=(1−ρ)2ρ2⋅2σa2+σs2+ρ
结论很明显,到达过程变异越大,系统平均排队时间越久,队列平均长度一定,方差越大,越容易局部突发拥塞,交换机 buffer 若太大,则利用率不足,若太小则遭遇突发时更容易丢包。
要避免拥塞,几乎唯一的方案就是降低到达过程的变异性,理想情况是变异系数为 0,且期望为 packet 长度,此即基于 packet 做 ECMP 负载均衡,其反面则是在 flow 长度方差很大的 flow 间做基于 flow 的 ECMP 负载均衡。
该结论用更一般的大数定律和中心极限定理诠释更容易直观理解。
将问题化简为:从期望为 e,方差为 v 的任意分布中采样作为单一 ECMP 链路负载,求其期望和方差。
设从某个分布中独立采样 n 个样本,记为 X 1 , X 2 , . . . X n X_1,X_2,...X_n X1,X2,...Xn,每个样本的期望为 E [ X i ] = e E[X_i]=e E[Xi]=e ,方差为 V a r ( X i ) = v \mathrm{Var}(X_i)=v Var(Xi)=v ,求样本均值 X ‾ = 1 n ∑ i = 1 n X i \overline X=\dfrac{1}{n}\sum_{i=1}^nX_i X=n1∑i=1nXi 的期望和方差。
推导很容易,直接给结论:
- 期望为 E [ X ‾ ] = e E[\overline X]=e E[X]=e ;
- 方差为 V a r ( X ‾ ) = v n \mathrm{Var}(\overline X)=\dfrac{v}{n} Var(X)=nv
将 n 看作 flow 数量,e 看作 flow 们平均长度,v 度量 flow 们长度变异性, E [ X ‾ ] E[\overline X] E[X] 看作系统平均负载,轻易可见,当 n 一定,e 越小,系统平均负载期望越小,v 越小,系统最大负载越小。理想情况下,e = 1,v = 0,即基于 packet 的 ECMP 负载均衡,而 v 越大,系统最大负载越大,此即基于 flow 的 ECMP 负载均衡。
也可以基于 ECMP 网络本身建模,会得到同样的结论。
设 ECMP 路径数为 M,flow 数为 N,第 i 条 flow 包数为随机变量 X i X_i Xi,期望为 μ \mu μ,方差为 σ 2 \sigma^2 σ2。
先看基于 flow 的负载均衡方案。路径 j 的负载为 S j = ∑ i ∈ 分配到 j X i S_j=\sum_{i\in 分配到j}X_i Sj=∑i∈分配到jXi,分配到路径 j 的 flow 数 K j ∼ B i n ( N , 1 M ) K_j\sim \mathrm{Bin}(N,\dfrac{1}{M}) Kj∼Bin(N,M1),路径 j 的期望负载为:
E [ S j ] = N M ⋅ μ E[S_j]=\dfrac{N}{M}\cdot \mu E[Sj]=MN⋅μ
根据条件方差分解公式:
V a r ( S j f l o w ) = E [ V a r ( S j ∣ K j ) ] + V a r ( E [ S j ∣ K j ] ) = . . . = N M ⋅ σ 2 + N M ⋅ ( 1 − 1 M ) ⋅ μ 2 \mathrm{Var}(S_j^{flow})=E[\mathrm{Var}(S_j|K_j)]+\mathrm{Var}(E[S_j|K_j])=...=\dfrac{N}{M}\cdot\sigma^2+\dfrac{N}{M}\cdot(1-\dfrac{1}{M})\cdot\mu^2 Var(Sjflow)=E[Var(Sj∣Kj)]+Var(E[Sj∣Kj])=...=MN⋅σ2+MN⋅(1−M1)⋅μ2
其中:
- 流内方差: N M ⋅ σ 2 \dfrac{N}{M}\cdot\sigma^2 MN⋅σ2 反映 flow 大小的波动;
- 流间方差: N M ⋅ ( 1 − 1 M ⋅ μ 2 ) \dfrac{N}{M}\cdot(1-\dfrac{1}{M}\cdot\mu^2) MN⋅(1−M1⋅μ2) 反映 flow 分配的不均匀性。
结论依旧,flow 大小变异越大,负载波动越大,越容易导致突发拥塞。
再来看基于 packet 的负载均衡方案。路径 j 的负载复合二项分布,即 S j ∼ B i n ( N ⋅ μ , 1 M ) S_j\sim \mathrm{Bin}(N\cdot\mu,\dfrac{1}{M}) Sj∼Bin(N⋅μ,M1),根据二项分布方差计算公式,得到方差:
V a r ( S j p a c k e t ) = N ⋅ μ ⋅ 1 M ( 1 − 1 M ) = ⋅ N M ( 1 − 1 M ) ⋅ μ \mathrm{Var}(S_j^{packet})=N\cdot\mu\cdot\dfrac{1}{M}(1-\dfrac{1}{M})=\cdot\dfrac{N}{M}(1-\dfrac{1}{M})\cdot\mu Var(Sjpacket)=N⋅μ⋅M1(1−M1)=⋅MN(1−M1)⋅μ
结论是:
V a r ( S j f l o w ) ≫ V a r ( S j p a c k e t ) \mathrm{Var}(S_j^{flow})\gg\mathrm{Var}(S_j^{packet}) Var(Sjflow)≫Var(Sjpacket)
有上述证明可见,ECMP 将很多大象流,小象流 hash 到同一个路径,这件事是统计律决定的,这件事是不可优化的。同时,这意味着 ECMP 在本质上和大象流是冲突的。
依照熵的概念,有长短,突发属性的 flow 为低熵流量,而独立的 packet 则为高熵流量,分布最均匀的流量熵值最高,最能避免作为低熵态的拥塞,这意味着流量不能有任何属性和模式,在所有等价路径均匀随机分布的 packet 是避免拥塞的唯一理想策略,利用可预测的反面,即不可预测性。
任何号称能为大象流,老鼠流传输调优的算法都会损伤全局效能,它们要么都是噱头,要么根本不知道自己做了什么。
或者,如果不想做新协议,至少应该将同质流扔进同一队列以降低统计不确定性,我做过这个事,称 flow-classification,详见 数据中心传输(5):减轻统计不确定性(数据中心传输(1~5) 是一个系列),云数据中心传输的出路。
浙江温州皮鞋湿,下雨进水不会胖。