NX-OS 9.3:ECMP 极化和“ip 负载共享......旋转”

网络工程 路由 cisco-nexus 电调 操作系统
2021-07-17 06:04:56

这是一个“为什么以及究竟如何工作”的问题。给定的问题已经解决。

问题:

我有兴趣了解“旋转”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,我不太确定我是什么看着。

叶脊拓扑,带有 VRF lite 和两台服务器

一般的:

  • 无 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 次)时,出口负载转移回单个出口链路。


1个回答

它工作的原因是,rotate 30即使所有输入(数据包头、入口端口索引等)都相同,您正在使用 配置该交换机以做出与相邻交换机不同的散列决策(隐式默认配置)。

您提到您熟悉旧的 CEF 技术(老实说,与我们今天的技术没有什么不同。)您可能还记得配置ip cef load-sharing algorithm universal哪个会导致每个节点生成一个用于影响散列算法输出的唯一数字。

通过为rotate <n>提供不同的值,您正在做同样的事情,但提供一个明确的值。这个想法是,在典型的数据中心网络中,您可以为rotate网络的每个拓扑级别配置不同的值,并且不太可能出现不需要的 ECMP 极化。在地铁环中,您也可以这样做。