TCP 转发 Nginx VS iptables 哪个稳?

2022-05-16 17:23:30 +08:00
 ab

没有负载均衡的需求

6702 次点击
所在节点    NGINX
43 条回复
FabricPath
2022-05-16 22:11:14 +08:00
@ryd994 tso 是在网卡 driver 收完,送到协议栈之前就完成了,netfilter 阶段看到的就是一个超大的 skb ;同理,出方向只要 dev 的 feature 带 tso ,那一路都会是一个大 skb ,直到真正的网卡驱动,或者中途某个不支持 tso 的 dev 时,才会被 gso 拆分成多个 skb 。你可以随便找个 docker 环境,起一个 bridge 的容器,在 host 侧的 veth 抓包,会发现 tcpdump 看到的都是大包,因为 veth 默认是开启了 tso 。
FabricPath
2022-05-16 22:13:14 +08:00
回到楼主的问题,nginx 会二次建联 tcp ,而 iptables 只是对同一条连接做修改。真因为如此,nginx 可以跨协议代理,比如 HTTPS 转 http 、quic 转 http ,而 iptables 是做不到的。综上,看需求,对性能有要求,只是做 L4 的连接修改,那选 iptables ,对性能没要求,那尽量 nginx ,毕竟 L7 的灵活性无敌
Rocketer
2022-05-16 22:16:27 +08:00
别懵,学一下 OSI 7 层模型很有用,也很简单。现在连各种培训班都会讲这个。
ab
2022-05-16 22:48:12 +08:00
heiher
2022-05-16 23:02:56 +08:00
@geeglo 感谢 @FabricPath 前面说法被证伪了,刚才查了一下资料也做了一下实验,开启 TSO 或 TSO 时,在 netfilter 确实是合并后的大 skb 。
ryd994
2022-05-17 01:44:26 +08:00
@geeglo
“用户态程序做的事情更多,CPU 反而能省下?”
我上面着一大段就是在解释,为什么 L4 代理可以比 L3 代理更快。
L4 代理并不是改每个包的地址,而是在建立了两个 TCP 连接,分别收发。这种情况下,两侧连接都可以充分利用硬件加速。
L3 代理因为不经过 TCP 协议栈,tso lro 都是用不了的。就要修改每个包的地址。

家用路由器为什么需要硬件 nat 加速?说白了就是 SoC 性能不足以处理每个包。软路由所需的 CPU 的性能 vs 硬路由的 SoC 的性能,这没法比。硬路由可以用更弱的 SoC 实现同样的性能(在有限的功能范围内),恰恰是说明了,硬件加速对于网络处理的重要性。

以上是对于比较稳定的高性能网络。瓶颈在硬件性能。

对于不稳定的网络,L4 代理可以减少重传和延迟,因此能提高单个连接的 throughput ,准确的说是 goodput 。对于这类网络,瓶颈在于 TCP 流控和重传。连接处理性能不是瓶颈。


以上是我原本的观点。

但是楼下 @FabricPath 说 nf 在 driver 上层,而 gro/lro 是对所有 TCP 包都有效,因此 nf 也可以享受到硬件加速。如果是这样的话,那 nf 的转发能力肯定是要比 Nginx 要强的。
bigbyto
2022-05-17 02:05:45 +08:00
@ryd994
@heiher
@geeglo
@FabricPath

感谢各位精彩的讨论
ryd994
2022-05-17 02:32:48 +08:00
@FabricPath 找到了两个 reporte bug:
https://support.hpe.com/hpesc/public/docDisplay?docId=c03168563&docLocale=en_US
http://ehaselwanter.com/en/blog/2014/11/02/mtu-issue--nope-it-is-lro-with-bridge-and-bond/

GRO LRO 导致 ip_forwarding 出问题,说明了 LRO 对 iptables 和后续的转发是有效的。或者说预期上应当有效。
但是由于某些驱动的 bug ,导致出错进而不得不关闭 GRO LRO ,这是另一回事了。
arloor
2022-05-17 02:46:22 +08:00
学术讨论之后想用 iptables 做转发的可以看看这个项目: https://github.com/arloor/iptablesUtils
方便的设置 nat 转发,不需要手敲命令了

或者可以用 nftables 的项目:
https://github.com/arloor/nftables-nat-rust
ab
2022-05-17 03:11:17 +08:00
@arloor #29 谢谢
geekvcn
2022-05-17 07:43:39 +08:00
@heiher 神论,建议多学习而不是半斤八两的时候急于误导别人
tramm
2022-05-17 08:40:21 +08:00
公司用的 Haproxy, 测试时用的 Nginx.

打算空下来搞搞 Envoy
heiher
2022-05-17 08:55:50 +08:00
@geekvcn 哈哈,确实不是非常清楚 TSO/GSO 的实现细节,结合平时的使用感受(我的 r8169 网卡不支持 TSO)就“推测”了一把,好在被及时指正了 :P
arloor
2022-05-17 14:13:38 +08:00
@arloor #29 增加了 10 个 star 了。。看来还是要找机会发一发才能涨 star 。。
FabricPath
2022-05-17 15:32:57 +08:00
@ryd994 lro 应该已经被 gro 淘汰了,没用过 lro ,这块儿不是很了解。nf 大部分钩子是夹在协议栈和 driver 之间的,协议栈不会去检查 dev 的 features ,所以 nf+协议栈+用户态看到的报文内容是相同。 区别是用户态在收发包的时候需要多一次内存拷贝,所以要实现相同的功能,任何情况下内核态的 iptables 都会比用户态的 nginx 性能要好。
比如都是做 L4 代理,在 rx 收到包之后,首包做完 dnat 后建 ct ,后续报文 nat 表的 hook 直接匹配 ct 就修改报文转发出去了,不会经过协议栈;同一个报文,nginx 是 rx->link->network->protocol->copy 到用户态->nginx 解析->把 data 发送到到 rs 的 socket->copy 到内核态->protocol->network->link->tx 。
另外关于硬件加速这部分,对于 x86 服务器来说,通常情况下只关注 csum offload 、tso 、tls offload ,只有这几个是真正硬件在做的,其他如 gso 、gro 都是纯软件实现。家用路由器的 nat 加速是针对特定场景定制的处理器,具体我不是很清楚它的实现方式,盲猜应该是快慢路径,iptables 处理建联过程,ct 建好后通过 sdk 下发到转发芯片上。
至于说要实现真正的硬件 offload ,目前有且仅有 mellanox 的 cx5 、cx6 的 switchdev sriov+tc flower offload 是在生产环境大规模使用过,当 tc flower 是 in_hw ,那 tcpdump 都看不到报文,全部在 eswitch 处理了(带 ct 的规则除外,ct offload 比较特殊)。
ttl123
2022-05-17 16:18:31 +08:00
@FabricPath 虽然看不懂,感觉你比较专业
tkl
2022-05-18 16:42:30 +08:00
@FabricPath
@heiher
@ryd994

https://imgur.com/a/UHKhPZn

https://github.com/fermads/node.js-process-load-balancing

我也觉得 iptables 更好,毕竟少了一层

云平台的虚拟防火墙的性能上不去?感觉有点偷换概念,你用 nginx 就没有瓶颈了?
ryd994
2022-05-18 16:56:10 +08:00
@tkl 根本问题不在多一层少一层,而在于能否充分利用硬件 offload 。高性能网络早已不是 CPU 加高频率硬扛可以扛下来的。而是要靠 offload 为主。
如果 iptables 同样能充分利用硬件,那当然 iptables 会快。
问题就在于这个如果是否成立,在多大程度上成立。
纯靠 iptables 的路由器有没有,有,但是用的是魔改内核和 netfilter 。比如博通的 ctf 。后来博通也开始搞硬件的 offload ,也就是 flow accelerator 。
FabricPath
2022-05-18 17:45:37 +08:00
@ryd994 不知道说的是哪家的防火墙有性能问题。云平台的防火墙的性能,不知道你是指 nfv 版的防火墙,还是普通的安全组。如果是安全组,各家公有云都是在 Host 侧的 dpdk 实现的,本来 Host 的 dpdk 就一定会有 ct ,连接一旦连接之后,都是在快路径匹配五元组转发,不会遍历流表,所以性能上不去是不存在的,至少目前没听说过国内国外那家公有云的安全组会影响影响。ACL 是无状态的,无 ct 的功能更不可能影响性能。唯一可能就是 nfv 的边界防火墙,或者入侵检测,对应阿里云的云防火墙,这种都是 dpdk 实现的 dpi ,如果说有的云厂商初期会选择用 x86 的 server 来用 iptables 做防火墙,那是有可能会有性能问题,不过迟早都会走向 dpdk 。
iptables 已经在云网络绝迹了,如果哪家云还在用 iptables 或者 iptables 类似物做产品,最好别买。

此外有什么“网络加速能力是内核态用不了,而只能用户态能用”,我理解是不存在这样特性的,如果有的话可以贴一下,我也学习一下。
iptables offload 这个事情社区推进很久了,但是 iptables 本身也即将退出历史舞台,而无论是 iptables 还是 nftables ,绝大部分场景都是用来做有状态服务,而有状态服务要做 offload 最难的地方就是要管理 ct ,网卡无法完成 ct offload 的闭环,需要将带 sync 、rst 、fin 等 flag 的报文送到内核来变更 ct 状态,并决定是否插入或删除硬件的 entry ,带来的问题就是对短连接性能影响较大,家用场景因为连接数少( 16k 以内),所以是没啥问题的。
关于网卡 offload 能力的 feature ,比如可以搜 NETIF_F_TSO ,来看哪些地方和 TSO 有关,理论上有它出现的地方都是在网卡 driver 。
ryd994
2022-05-18 18:25:17 +08:00
@FabricPath
“如果哪家云还在用 iptables 或者 iptables 类似物做产品,最好别买”
我说的就是 Azure 。Azure 使用 VFP 处理数据包。就算单纯匹配 5 元组,但是因为还有各种封包 /解封包操作。单连接带宽是过不了 10G 的。你想要满血网络,就必定要靠硬件加速。Azure 用的是 FPGA 。多连接当然可以靠堆 CPU 靠 RSS 硬抗,但是那就贵了。
AWS 虽然是以 smartnic 为主,但是碰到复杂情况硬件不支持就只能靠软件扛了。
GCP 是以 DPDK/自研软件处理,但是 GCP 单连接是跑不满线速的。
这是当年的性能比较: https://blog.acolyer.org/2018/05/01/azure-accelerated-networking-smartnics-in-the-public-cloud/
当然这里 Azure 取巧了:比的是单线程带宽


言归正传,楼主的问题是基于原版 netfilter vs nginx 的情况,扯 dpdk 那就是完全两回事了。咱们先把 dpdk 放下。

“网络加速能力是内核态用不了,而只能用户态能用”
我从来没说过这话。理论上当然 iptables 干什么都行。魔改内核干什么都行。但是原版内核还是有一些原则需要遵守。
iptables nat 转发不能使用 LRO 是因为 LRO 破坏了 end-to-end 原则。L3 的 ip_forwarding 不应该去修改 L4 的内容。GRO 保留了包边界,因此应当是可以使用的。但是 GRO 的效果和硬件支持的 LRO 比,哪个更好还未可知。

说实话,我近年都是搞 Windows 网络为主,Linux 并不是我的强项。但是既然这个问题也算是我分内之事,我会再研究一下,不希望误导大家。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/853232

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX