背景介绍
我在高流量下运行两台服务器,一台使用 ubuntu 12.04 (linux 3.2.0-69-generic),另一台使用 ubuntu 14.04 (linux 3.13.0-52-generic)。我现在正在尝试保护这两台服务器。它们都具有非常相似的硬件资源(CPU 数量相同,但 12.04 只有 8 GB 的 RAM,而 14.04 有 16 GB)。
我想启用 ufw 防火墙,但遇到了 nf_conntrack 表已满的问题。数据包基本上被丢弃了。
我找到了一个解决方案,即降低超时时间并增加表大小以及存储桶数量。即:
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_max = 196608
net.netfilter.nf_conntrack_buckets = 24576
这些值会得到正确更新,并且重启后仍然有效。(请参阅这个博客) 我还看到 conntrack_count 远高于默认值,因此我确信这在两台服务器上都有效。值保持在限制以下,因此我确信它没问题。
问题
12.04 服务器在高负载下运行良好,但 14.04 不断丢包,导致客户端超时。现在在 14.04 上启动时,我可以在 kern.log 中看到以下行:
TCP established hash table entries: 131072 (order: 8, 1048576 bytes)
而在 12.04 上,它是:
TCP established hash table entries: 524288 (order: 11, 8388608 bytes)
我怀疑这可能是我的服务器丢包的原因,因为这个表对于 14.04 上的流量来说可能太小了。
因此我尝试寻找设置此大小的方法,并找到了参数 thash_entries看这里解释)。但是,我无法使用 sysctl 进行设置。
我的问题是:
- 这个 tcp 连接表真的是我的麻烦根源吗?还是我应该去别处看看?
- 如果是,那么我该如何设置它并使其在重启后继续存在?
在此先感谢您的帮助,如果您需要更多帮助,请随时询问我。
PS:我更像是一名开发人员,而不是系统专家,因此我将非常感激任何详细的答案:)
答案1
调整 Linux 内核以实现高网络吞吐量是一门基于平衡的艺术。
增加连接跟踪表是好的,但这意味着可能使用更多的套接字,这反过来意味着系统需要更多的文件描述符,然后轮子继续前进......
对于您来说,我将从以下内核设置开始:
net.core.somaxconn
和
fs.file-max
第一个参数决定内核可以维持的打开套接字数量。第二个参数用于设置内核支持的文件描述符数量。
然后还有可以进一步调整的 SYN 积压。
net.ipv4.tcp_max_syn_backlog
将设置等待服务器 ACK 的连接数量。
net.ipv4.tcp_syncookies
为了使 SYN Backlog 正常工作,您需要启用 TCP SYN cookie。
最后,还可以进行一些调整,例如启用 TIME_WAIT 连接重用。
net.ipv4.tcp_tw_reuse
这可以潜在地减少当您收到峰值时打开的“新”插座数量。
这只是冰山一角,我对大容量 Linux/Unix 系统的经验是,你需要花几个月的时间对其进行调整,才能达到正确的平衡。
请务必查看错误/var/log/kern.log
并/var/log/messages
帮助进一步排除故障。