10/20/40Gbps nginx大文件缓存webserver [20Gbps达到]

Yar*_*Dot 11 nginx 10gbethernet irq

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

情况

我们有一个视频共享代理服务器,可以从它后面的慢速存储服务器上卸载峰值。所有流量仅为 HTTP。服务器充当反向代理(未缓存在服务器上的文件)和网络服务器(存储在本地驱动器上的文件)。

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

缓存机制是独立实现的,这个问题与缓存本身无关,因为它工作得很好——目前提供 14Gbps,传递给后端服务器的速度仅为 2Gbps。所以缓存使用很好。

目标

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

硬件 1

硬件: Supermicro SC825, X11SSL-F, Xeon E3-1230v5 (4C/8T@3.4GHz), 16GB DDR4 RAM, 2x Supermicro 10G STGN-i1S (LACP L3+4)

固态硬盘:1x 512GB 三星,2x 500GB 三星,2x480GB Intel 535,1x 240GB Intel 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 内存时出现问题造成的。

硬件 2

硬件:Supermicro SC119TQ、X10DRW-i、2x Xeon E5-2609v4 (8C/8T@1.70GHz)、128GB DDR4 RAM、2x Supermicro 10G STGN-i1S

SSD,系统配置同硬件1。Nginx是sendfile on(aio/sendfile进一步对比)。

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

这看起来更好,所以现在我们有一个在高峰期工作的服务器,我们可以尝试一些优化。

Sendfile 与 aio 线程

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

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

对比

  • 发送文件

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

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

发送文件开/关

只是尝试打开/关闭发送。除了重新调度中断外,没有任何变化。

在此处输入图片说明 在此处输入图片说明

irqbalancer 作为服务器/cron/禁用

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

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

我找不到图表中的问题,第二天又发生了这种情况,我登录到服务器并看到一个核心处于 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?

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

use*_*461 9

免责声明:同样的建议适用于所有超过 10Gbps 的服务。包括但不限于负载均衡器、缓存服务器、网络服务器(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...]
Run Code Online (Sandbox Code Playgroud)

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

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

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

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]
Run Code Online (Sandbox Code Playgroud)

反向代理正在双向转发所有消息。负载始终为 50/50,总流量翻倍。

启用缓存会变得更加复杂。请求可能会转移到硬盘驱动器,其数据可能会缓存在内存中。

注意:我将忽略本文中的缓存方面。我们将专注于在网络上获得 10-40 Gbps。了解数据是否来自缓存并优化该缓存是另一个主题,无论哪种方式,它都会通过网络推送。

单核限制

负载均衡是单核的(尤其是 TCP 均衡)。添加内核不会使其更快,但可以使其更慢。

使用简单模式(例如,IP、URL、基于 cookie 的 HTTP 平衡。反向代理即时读取标头,它不解析也不处理严格意义上的 HTTP 请求)。

在 HTTPS 模式下,SSL 解密/加密比代理所需的一切都更加密集。SSL 流量可以而且应该被分配到多个核心上。

安全证书

鉴于您通过 SSL 执行所有操作。你会想要优化那部分。

即时加密和解密 40 Gbps 是一项了不起的成就。

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

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

IRQ 和核心固定

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

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

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

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

以太网适配器

网卡承担了很多繁重的工作。在性能方面,所有设备和制造商都不尽相同。

忘记主板上的集成适配器(服务器或消费类主板无关紧要),它们很糟糕。

TCP卸载

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

我们不想要一张相对较快的卡片,我们想要一张带有所有花里胡哨的卡片

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

只有一个在表选项:Solarflare的- HFT公司和CDN的秘密武器。

世界分为两种人:“了解 SolarFlare 的人”和“不了解 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
Run Code Online (Sandbox Code Playgroud)

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

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

(注:单机 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 网卡比 PCIe 总线更有希望。

其他

我们可以超越其他限制。关键是硬件具有物理定律固有的硬限制。

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

网络骨干

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

此外,带宽必须是端到端的,所以你有什么样的链接给用户?

上次我与我的数据中心人员检查了一个 1000 万用户的小项目时,他很清楚最多只有 2 个 10 Gbits 的互联网链接。

硬盘驱动器

iostat -xtc 3

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

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

CPU选择

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

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

SSL 受益于多核,因此要针对多核。

长话短说:理想的 CPU 是具有最高可用频率和许多内核的最新 CPU。选择最贵的,大概就是这样:D

发送文件()

发送文件开启

高性能网络服务器的现代内核的最大进步。

最后说明

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
...
Run Code Online (Sandbox Code Playgroud)

一件事固定在一个 CPU 上。这就是要走的路。

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

有很多东西需要微调,其中一些可能是一本小书的主题。玩得开心对所有这些进行基准测试。回来公布结果。


小智 0

由于声誉,我还无法发表评论,所以必须添加答案......

在第一个例子中,你说:

有两件事引起了我的注意。第一个是大量的 IRQ。不幸的是,在这种情况下,我没有来自 /proc/interrupts 的图表。第二件事是系统负载过高,我认为这是由于 kswapd0 仅在 16G RAM 上工作时出现问题造成的。

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

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

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

    虽然从表面上看,这看起来像是 CPU 问题,但如果发生大量硬或软页面错误,高软中断百分比可能只是指向内存。我认为泄露的信息是 IRQ 突然升级,在 19:00 左右以牺牲系统 CPU 为代价。

从我从规格中看到的,除了以下内容之外,一切看起来都一样:

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