这是一个“为什么以及究竟如何工作”的问题。给定的问题已经解决。
问题:
我有兴趣了解“旋转”ip load-sharing address source-destination port source-destination rotate <value>
实际上做了什么。文档(据我所知,见下文)所说的“64 位流”是什么?
这些 64 位中有什么?使用时是 64 位concatenation
吗?
我也会很高兴地指出 Nexus 9k3 的 ECMP 行为的高级文档。看来我的 google-foo 不够好。
背后的故事
使用 ...
ip load-sharing address source-destination port source-destination rotate 30
...在脊椎上,我能够解决一个问题,该问题看起来非常像我理解的 CEF ECMP 极化问题,但由于 Nexus 实际上并没有运行 CEF,我不太确定我是什么看着。
一般的:
- 无 VXLAN,无底层/覆盖
- L3 端口子文件上的普通路由
- 用例都在同一个 VRF 中
脊椎:
- 运行 NXOS 9.3(2) 的 Nexus 3164Q
叶子:
- 运行 7.0(3)I4(8b) 的 Nexus 3164Q 的 VPC 对
- VRF lite,每个 VRF 有一个 Looppack 接口
- VLAN 是叶子对本地的
- SVI + HSRPv2 用于本地 VLAN/子网
- 附有 2x10G MLAG (VPC) 的服务器
路由和链接:
- 刺和叶子:VRF lite,每个 VRF 有一个 Loobpack 接口
- 链路 A 到 H 是给定 40G 链路的 802.1q 标记子接口,
- 链接 A 到 H 是“未编号的”
- 链接 A 到 H 是“ospf 网络类型点对点”
- OSPF,单区域,无调谐,参考带宽400G
- 叶子对远程叶子对的子网有 2 条等价路由,每个脊一个
- Spines 有 2 个等价路由,用于叶子之外的子网,每个半叶一个
问题:
服务器管理员报告说,使用 iPerf 的 8 或 16 个并行 TCP 会话,他只能从 Server50(左)到 Server51(右)获得 2x5Gbps。
- 所有流的 Src 和 Dst IP 都相同
- 所有流的 Dst 端口都相同
- 每个流的 Src 端口都是唯一的
分析:
查看所涉及接口的负载,我们可以很快看到......
- 服务器 50 在其 LACP 包中均匀地共享其流量,因此 Leaf101/102 各获得总负载的 50%
- Leaf101/102 然后在 A&C 和 B&D 链路上均匀地分担上游流的负载,因此每个朝向脊的链路都获得了 25% 的负载
- Spine11 负载共享所有下行链路 E 到 Leaf201(负载的 50%)
- Spine12 负载共享所有下行链路 F 到 Leaf201(负载的 50%)
- 从 Leaf201 到 server51 的 10G 服务器端口有点超额订阅
- TCP 的流量控制介入了,它总共达到了大约 10G。
注意事项
- 叶子上游的负载共享似乎工作得很好
- 脊椎下游的负载共享似乎更喜欢单个链接
- 如果事情变得不走运,并且两个刺都选择将链接优先于叶的同一半部分,则可能会损失一半的吞吐量。
所以这一切都是有道理的。但是为什么会这样呢?
研究
有许多文档和博客文章解释了 CEF 的极化以及如何避免它,但我很难找到关于 NXOS 和 9300 系列的相同深入信息。
注意:3164Q 比 3100 系列交换机更像是 9300(已经从硬件的外观开始) - 它甚至与 9300 系列共享大部分配置指南、软件版本和发行说明,而不是 3000 /3100 系列(请参阅Cisco 自己的关于 3164Q 的自述文件)
我能挖掘到的最好的可能是: Cisco Nexus 9000 系列 NX-OS 单播路由配置指南,9.3(x) 版,章节:管理单播 RIB 和 FIB
引自:
该旋转选项使散列算法旋转链接采摘的选择,这样它不会不断地选择网络的所有节点的链路。它通过影响散列算法的位模式来实现。此选项将流从一个链接转移到另一个链接,并在多个链接上对来自第一个 ECMP 级别的已经负载平衡(极化)的流量进行负载平衡。
如果指定旋转值,则 64 位流将从循环旋转中的该位位置开始解释。旋转范围为 1 到 63,默认为 32。
注意 对于多层第 3 层拓扑,极化是可能的。为避免极化,请在拓扑的每一层使用不同的旋转位。
所以我开始研究脊椎的负载共享行为。
spine11# show ip load-sharing
IPv4/IPv6 ECMP load sharing:
Universal-id (Random Seed): 3549312827
Load-share mode : address source-destination port source-destination
GRE-Outer hash is disabled
Concatenation is disabled
Rotate: 32
我运行了一系列带有流参数的命令(我从 iPerf 的输出中知道),每组流参数一个
spine11# show routing hash 10.33.50.238 10.33.51.238 ip-proto 6 45440 5001 vrf VRFNAME
Load-share parameters used for software forwarding:
load-share mode: address source-destination port source-destination
Hash for VRF "VRFNAME"
Hashing to path *Eth1/51.301
Out Interface: Eth1/51.301
For route:
10.33.51.0/24, ubest/mbest: 2/0
*via 10.33.63.11, Eth1/19.301, [110/411], 19w0d, ospf-30000, intra
*via 10.33.63.12, Eth1/51.301, [110/411], 19w0d, ospf-30000, intra
我运行了 16 个 TCP 会话,并使用所有确切参数运行此命令 16 次,链接 E 得到 8 个,链接 H 得到 8 个(参见图表)。
从那以后,人们应该期望spine11 在E 和H 之间进行负载共享,但是......
...由于spine11 只得到一半(8/16)的流(所有这些都已经被leaf101/leaf102 散列/平衡为“左”流),spine11 的散列将强制得出单个散列结果。这一切都指向一个单一的出口链接。
这就是 ECMP 极化。
解决方案:
当数据流从服务器 50 流向服务器 51 时,我在脊椎上运行了这个命令,正如思科文档(见上面的链接)所暗示的那样,用于多层第 3 层拓扑。
ip load-sharing address source-destination port source-destination rotate 30
(设置其他值而不是 32,这是默认值)
很快,spine11 上的出口负载开始在链路 E 和 H 之间均匀分布,之前它们都在一个链路上。因此,服务器现在的总吞吐量达到了 2x10Gbps。
此外,当恢复到默认值(旋转 32 次)时,出口负载转移回单个出口链路。