调整Linux IP路由参数 - secret_interval和tcp_mem

Modified on: Sat, 27 Jul 2019 11:20:02 +0800

今天我们的一个HAProxy VM遇到了一点故障转移问题。当我们挖掘它时,我们发现了这个:

Jan 26 07:41:45 haproxy2 kernel: [226818.070059] __ratelimit: 10 callbacks suppressed
Jan 26 07:41:45 haproxy2 kernel: [226818.070064] Out of socket memory
Jan 26 07:41:47 haproxy2 kernel: [226819.560048] Out of socket memory
Jan 26 07:41:49 haproxy2 kernel: [226822.030044] Out of socket memory

根据此链接,显然与低默认值有关net.ipv4.tcp_mem的设置。所以我们将它们的默认值增加了4倍(这是Ubuntu Server,不确定Linux风格是否重要):

current values are:    45984   61312   91968
new values are:       183936  245248  367872

之后,我们开始看到一条奇怪的错误消息:

Jan 26 08:18:49 haproxy1 kernel: [ 2291.579726] Route hash chain too long!
Jan 26 08:18:49 haproxy1 kernel: [ 2291.579732] Adjust your secret_interval!

嘘.. 这是秘密!!

这显然与/proc/sys/net/ipv4/route/secret_interval有关,默认为600并控制定期刷新路由缓存

  

secret_interval指示内核清除所有路由的频率
  哈希条目,无论它们有多新/旧。在我们的环境中这是
  一般都不好。 CPU将忙于重建每个数千个条目
  每次清除缓存时都为秒。但是我们将其设置为运行一次
  保持内存泄漏的一天(虽然我们从未有过)。

虽然我们很乐意减少这种情况,但建议定期删除整个路由缓存似乎很奇怪,而不是简单地将旧值更快地推出路由缓存。

经过一番调查后,我们发现/proc/sys/net/ipv4/route/gc_elasticity,这似乎是更好的选择,可以检查路由表的大小:

  

gc_elasticity最好被描述为内核的平均桶深度
  在它开始到期路由哈希条目之前将接受。这会有所帮助
  保持活跃路线的上限。

我们将弹性从8调整到4,希望路由缓存更加积极地修剪。 secret_interval对我们来说感觉不正确。但是有很多设置,目前还不清楚哪些是真正适合的方式。

  • / proc / sys / net / ipv4 / route / gc_elasticity(8)
  • / proc / sys / net / ipv4 / route / gc_interval(60)
  • / proc / sys / net / ipv4 / route / gc_min_interval(0)
  • / proc / sys / net / ipv4 / route / gc_timeout(300)
  • / proc / sys / net / ipv4 / route / secret_interval(600)
  • / proc / sys / net / ipv4 / route / gc_thresh(?)
  • rhash_entries(内核参数,默认未知?)

我们不想让Linux路由更糟,所以我们有点害怕搞乱其中一些设置。

对于高流量的HAProxy实例,有人可以建议哪些路由参数最适合调整吗?

作者:,Jeff Atwood

最佳答案

我从未遇到过这个问题。但是,您应该增加哈希表宽度以减小其深度。使用“dmesg”,您将看到当前有多少条目:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

您可以使用内核引导命令行参数rhash_entries更改此值。首先手动尝试然后将其添加到lilo.confgrub.conf

例如:kernel vmlinux rhash_entries=131072

你可能有一个非常有限的哈希表,因为你已经为你的HAProxy VM分配了很少的内存(路由哈希大小根据总RAM调整)。

关于tcp_mem,请注意。您的初始设置让我觉得您运行的是1 GB的RAM,其中1/3可以分配给TCP套接字。现在您已经为TCP套接字分配了367872 * 4096字节= 1.5 GB的RAM。你应该非常小心,不要耗尽内存。根据经验,将1/3的内存分配给HAProxy,另外1/3分配给TCP堆栈,最后1/3分配给系统的其余部分。

我怀疑您的“out of socket memory”消息来自tcp_rmemtcp_wmem中的默认设置。默认情况下,每个插槽的输出分配为64 kB,输入为87 kB。对于代理连接,这意味着总共300 kB,仅用于套接字缓冲区。为HAProxy添加16或32 kB,你会发现使用1 GB的RAM你只能支持3000个连接。

通过更改tcp_rmemtcp_wmem(中间参数)的默认设置,可以大大降低内存。我得到了良好的结果,写缓冲区的值低至4096,tcp_rmem(5或11个TCP段)的值为7300或16060。您可以在不重新启动的情况下更改这些设置,但它们仅适用于新连接。

如果您不想过多地触摸sysctls,最新的HAProxy,1.4- dev8,允许您从全局配置和每一侧(客户端或服务器)调整这些参数。

我希望这有帮助!


相关问答

添加新评论