你想做的事是错的,别做

你想做的事是错的,别做

在这个问题中,我想找到从单个服务器提供 40Gbps 的最佳配置/硬件。

情况

我们有一个视频共享代理服务器,可卸载其后方缓慢存储服务器的峰值。所有流量均为 HTTP。该服务器充当反向代理(未缓存在服务器上的文件)和 Web 服务器(存储在本地驱动器上的文件)。

后端存储服务器上目前有大约 100TB 的文件,并且还在不断增长。

缓存机制是独立实现的,这个问题与缓存本身无关,因为它运行良好 - 目前提供 14Gbps,仅向后端服务器传递 2Gbps。因此缓存使用率很好。

目标

单台机器实现40Gbps甚至更高的吞吐量。

硬件 1

硬件:Supermicro SC825,X11SSL-F,Xeon E3-1230v5 (4C/[电子邮件保护])、16GB DDR4 RAM、2x Supermicro 10G STGN-i1S (LACP L3+4)

SSD:1x 512GB 三星、2x 500GB 三星、2x480GB 英特尔 535、1x 240GB 英特尔 S3500

系统:

  • irqbalancer 已停止
  • 为每个接口设置 irq_affinity(通过 ixgbe 驱动程序 tarball 中的脚本)
  • ixgbe-4.3.15
  • I/O 调度程序截止时间
  • iptables 为空(卸载模块)
  • 文件系统:XFS

Nginx的:

  • 发送文件关闭
  • aio线程
  • 方向 1M
  • tcp_nopush 开启
  • tcp_nodelay 开启

在此处输入图片描述 在此处输入图片描述 在此处输入图片描述

从图表上看,我们能够达到 12.5Gbps。不幸的是,服务器没有响应。

有两件事引起了我的注意。第一件是大量的 IRQ。在这种情况下,遗憾的是我没有来自 /proc/interrupts 的图表。第二件事是系统负载过高,我认为这是由于 kswapd0 无法在仅使用 16G RAM 的情况下工作所致。

硬件 2

硬件:Supermicro SC119TQ、X10DRW-i、2x Xeon E5-2609v4(8C/[电子邮件保护])、128GB DDR4 RAM、2 个 Supermicro 10G STGN-i1S

SSD,系统配置与硬件1相同。Nginx 已开启 sendfile(进一步比较了 aio/sendfile)。

在此处输入图片描述 在此处输入图片描述 在此处输入图片描述

这似乎更好一些,所以现在我们有了一台在高峰期工作的服务器,我们可以尝试一些优化。

Sendfile 与 aio 线程

我尝试禁用 sendfile 并改用 aio 线程。

  • 发送文件关闭
  • aio线程
  • directio 1M(与我们拥有的所有文件相匹配)

对比

  • 发送文件

然后在 15:00 我切换回 sendfile 并重新加载 nginx(因此需要一段时间才能完成现有连接)。驱动器利用率(通过 iostat 测量)下降了,这很好。流量没有任何变化(不幸的是 zabbix 决定不从 bond0 收集数据)。

在此处输入图片描述 在此处输入图片描述 在此处输入图片描述

发送文件开启/关闭

刚刚尝试打开/关闭发送。除了重新安排中断外,没有任何变化。

在此处输入图片描述 在此处输入图片描述

irqbalancer 作为服务器/cron/已禁用

正如@lsd 提到的,我尝试设置 irqbalancer 通过 cron 执行:

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null

不幸的是,它对我的​​情况没有帮助。其中一块网卡开始出现异常:

在此处输入图片描述

我无法在图表中找到问题所在,第二天再次发生这种情况时,我登录到服务器并看到一个核心达到了 100%(系统使用率)。

我尝试将irqbalance作为服务启动,结果还是一样。

然后我决定使用 set_irq_affinity 脚本,它立即解决了问题并且服务器再次推到了 17Gbps。

硬件 3

我们确实升级到了新硬件:2U 24 (+2) 驱动器机箱 (6xSFF)、2x Xeon E5-2620v4、64GB DDR4 RAM (4x16GB 模块)、13x SSD、2x Supermicro (带英特尔芯片) 网卡。新 CPU 大大提高了性能。

当前设置保持不变 - sendfile 等。唯一的区别是我们只让一个 CPU 处理两个网卡(通过 set_irq_affinity 脚本)。

已达到 20Gbps 的限制。

在此处输入图片描述 在此处输入图片描述

下一个目标?30Gbps。


欢迎向我提出改进性能的想法。我很乐意进行现场测试并在此分享一些重要图表。

有什么想法如何处理 CPU 上的大量 SoftIRQ?

这不是容量规划的问题——我已经有了硬件和流量。我总是可以将流量分流到几台服务器(无论如何我将来都必须这样做),然后用钱解决问题。然而,这是一个关于实际场景中的系统优化和性能调整的问题。

答案1

免责声明:同样的建议适用于所有超过 10Gbps 的服务。包括但不限于负载平衡器、缓存服务器、Web 服务器(HAProxy、Varnish、nginx、tomcat 等)

你想做的事是错的,别做

改用 CDN

CDN 旨在提供可缓存的静态内容。使用合适的工具来完成工作(akamai、MaxCDN、cloudflare、cloudfront 等)

任何 CDN,即使是免费的,都会比您自己所能实现的效果更好。

改为水平缩放

我预计一台服务器无需太多调整即可处理 1-5Gbps(注意:仅提供静态文件)。通过高级调整,通常可以达到 8-10Gbps。

尽管如此单个盒子所能容纳的东西有很多硬性限制。你应该选择水平扩展。

运行一个盒子,尝试、测量、基准测试、优化......直到该盒子可靠且值得信赖并且其功能得到很好的确定,然后在前面放置更多类似的盒子和全局负载均衡器。

有几个全局负载平衡选项:大多数 CDN 可以做到这一点,DNS 循环,ELB/Google 负载平衡器......

让我们忽略好的做法,继续做下去

了解流量模式

            WITHOUT REVERSE PROXY

[request ]  user ===(rx)==> backend application
[response]  user <==(tx)===     [processing...]

有两件事需要考虑:带宽和方向(发射或接收)。

小文件的 tx/rx 是 50/50,因为 HTTP 标头和 TCP 开销大于文件内容。

大文件是 90/10 tx/rx,因为请求大小与响应大小相比可以忽略不计。

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]

反向代理正在双向中继所有消息。负载始终是 50/50,总流量加倍。

启用缓存后情况会变得更加复杂。请求可能会被转移到硬盘,而硬盘的数据可能会被缓存在内存中。

笔记:在这篇文章中,我将忽略缓存方面的问题。我们将重点关注如何让网络达到 10-40 Gbps。了解数据是否来自缓存并优化该缓存是另一个话题,无论如何,数据都会通过网络传输。

Monocore 限制

负载平衡是单核的(尤其是 TCP 平衡)。增加核心不会使其更快,但可能会使其更慢。

与简单模式的 HTTP 平衡相同(例如基于 IP、URL、cookie。反向代理动态读取标头,严格意义上来说,它不会解析或处理 HTTP 请求)。

在 HTTPS 模式下,SSL 解密/加密比代理所需的其他所有操作都更为复杂。SSL 流量可以且应该分散到多个核心上。

SSL

假设您通过 SSL 进行所有操作。您将需要优化该部分。

动态加密和解密 40 Gbps 是一项相当大的成就。

采用具有 AES-NI 指令(用于 SSL 操作)的最新一代处理器。

调整证书使用的算法。有很多算法。您需要一个对您的 CPU 最有效的算法(进行基准测试),同时得到客户端的支持并且足够安全(没有必要过度加密)。

IRQ 和核心固定

当有新数据需要读取时,网卡会产生中断 (IRQ),并且 CPU 会被抢占以立即处理队列。这是在内核和/或设备驱动程序中运行的操作,并且严格来说是单核的。

它可能是最大的 CPU 消耗者,因为有数十亿的数据包朝各个方向发出。

为网卡分配一个唯一的 IRQ 号并将其固定到特定的核心(参见 Linux 或 BIOS 设置)。

将反向代理固定到其他核心。我们不希望这两件事互相干扰。

以太网适配器

网卡承担着许多繁重的工作。所有设备和制造商的性能并不相同。

忘记主板上的集成适配器(无论是服务器主板还是消费者主板),它们都很糟糕。

TCP 卸载

TCP 是一种在处理方面非常密集的协议(校验和、ACK、重传、重组数据包等)。内核处理大部分工作,但如果网卡支持,则可以将一些操作卸载到网卡上。

我们不想只是一张相对较快的卡,我们想要一个带有所有花哨功能的产品。

忘掉英特尔、Mellanox、戴尔、惠普等吧。他们不支持所有这些。

摆在桌面上的选项只有一个:太阳耀斑--HFT 公司和 CDN 的秘密武器。

这个世界分为两种人:“了解 SolarFlare 的人“ 和 ”那些没有“。(第一组严格等同于“从事 10 Gbps 网络并关心每个比特的人“)。但我跑题了,让我们集中注意力吧:D

内核 TCP 调优

内核网络缓冲区有选项sysctl.conf。这些设置有什么作用或不做什么。我真的不知道。

net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default

net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem

使用这些设置是过度优化的明确标志(即通常无用或适得其反)。

考虑到极端的要求,这在特殊情况下可能是有意义的。

(注意:单个盒子上 40Gbps 是过度优化。合理的路线是水平扩展。)

一些物理限制

内存带宽

有关内存带宽的一些数字(大部分以 GB/s 为单位):http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3/index.html

假设内存带宽范围是 150-300 Gbps(理想条件下的最大限度)。

所有数据包都必须在某个时刻进入内存。仅以 40 Gbps 的线速接收数据就会给系统带来沉重的负担。

还有能力处理数据吗?好吧,我们不要对此抱有太高的期望。只是说说而已 ^^

PCI-Express 总线

PCIe 2.0 每通道 4 Gb/s。PCIe 3.0 每通道 8 Gbps(并非所有通道都适用于 PCI 卡)。

如果连接器的长度小于 v3.0 规范中的 16 倍,则具有单个以太网端口的 40 Gbps NIC 比 PCIe 总线更有前景。

其他

我们可以讨论其他限制。关键是硬件有物理定律固有的硬性限制。

软件不可能比其运行的硬件做得更好。

网络主干

所有这些数据包最终都要经过交换机和路由器,到达某个地方。10 Gbps 交换机和路由器 [几乎] 是商品。40 Gbps 绝对不是。

此外,带宽必须是端到端的,那么您与用户之间有什么样的链接呢?

上次我和数据中心的工作人员讨论一个拥有 1000 万用户的小型项目时,他非常清楚最多只能有 2x 10 Gbits 的互联网链接。

硬盘驱动器

iostat -xtc 3

指标按读取和写入分开。检查队列(< 1 为好)、延迟(< 1 毫秒为好)和传输速度(越高越好)。

如果磁盘速度很慢,解决方案是在 raid 10 中放入更多更大的 SSD。(请注意,SSD 带宽随着 SSD 大小线性增加)。

CPU 选择

IRQ 和其他瓶颈仅在一个核心上运行,因此目标是具有最高单核性能(即最高频率)的 CPU。

SSL 加密/解密需要 AES-NI 指令,因此仅针对 CPU 的最新版本。

SSL 受益于多核,因此目标是实现多核。

长话短说:理想的 CPU 是最新的、频率最高、内核多的 CPU。只需选择最贵的,可能就够了 :D

发送文件()

开启 Sendfile

简单来说,这是现代内核在高性能网络服务器方面取得的最大进步。

最后说明

1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...

把一件事固定在一个 CPU 上。这才是正确做法。

一个 NIC 通向外部世界。一个 NIC 通向内部网络。分担责任总是好的(尽管双 40 Gbps NIC 可能有点过头了)。

有很多事情需要微调,其中一些可以作为一本小书的主题。祝你对所有这些进行基准测试愉快。回来发布结果。

答案2

由于声誉问题,我暂时还不能发表评论,所以必须添加答案……

在第一个例子中,你说:

有两件事引起了我的注意。第一件是大量的 IRQ。在这种情况下,遗憾的是我没有来自 /proc/interrupts 的图表。第二件事是系统负载过高,我认为这是由于 kswapd0 无法在仅使用 16G RAM 的情况下工作所致。

完全同意这些都是重要的观点。

  1. 尝试使用 collectd 代理,它可以收集 IRQ 并使用 RRD 存储。

  2. 您有内存使用情况的图表吗?

    虽然从表面上看,这看起来像是 CPU 问题,但如果发生大量硬页面错误或软页面错误,那么高软中断百分比可能只是指向内存。我认为,问题在于 IRQ 突然增加,大约在 19:00 时系统 CPU 会因此受损。

从规格上看,除了以下情况外,其他一切看起来都一样:

  • 记忆
  • CPU 型号 - 除非我弄错了,否则基准测试表明它们应该是相似的,在这种情况下,我更喜欢具有更少更快内核的盒子。

相关内容