在这个问题中,我想找到从单个服务器提供 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 的情况下工作所致。
完全同意这些都是重要的观点。
尝试使用 collectd 代理,它可以收集 IRQ 并使用 RRD 存储。
您有内存使用情况的图表吗?
虽然从表面上看,这看起来像是 CPU 问题,但如果发生大量硬页面错误或软页面错误,那么高软中断百分比可能只是指向内存。我认为,问题在于 IRQ 突然增加,大约在 19:00 时系统 CPU 会因此受损。
从规格上看,除了以下情况外,其他一切看起来都一样:
- 记忆
- CPU 型号 - 除非我弄错了,否则基准测试表明它们应该是相似的,在这种情况下,我更喜欢具有更少更快内核的盒子。