Netfilter conntrack 性能调整
原文档最新版本可以在下面这个地址找到(发表本文时最新版是v0.8):
http://www.wallfire.org/misc/netfilter_conntrack_perf.txt
读书笔记总结:(主要是参考网上已有v0.6版的翻译,加入了最新版v0.8的一些更新)
注:为方便读者快速掌握重要信息,请重点关注红色字体
概念
====================
-允许的最大跟踪连接条目:CONNTRACK_MAX
-存储跟踪连接条目列表的哈西表的大小:HASHSIZE
-每个哈西表的条目(叫一个bucket),包含了一个链接起来的跟踪连接条目
-哈希表大小HASHSIZE,表现为 条目bucket的多少,在iptables启动时在日志中会显示。
CONNTRACK_MAX is the maximum number of “sessions” (connection tracking entries)
that can be handled simultaneously by netfilter in kernel memory.
这里我们可以调整两个参数:
-允许的最大跟踪连接条目,在这篇文档中我们叫作CONNTRACK_MAX
-存储跟踪连接条目列表的哈西表的大小,在这篇文档中我们叫做HASHSIZE(下面是这个结构的描述)
CONNTRACK_MAX是在内核内存中netfilter可以同时处理的“任务”(连接跟踪条目)。
一个跟踪连接的条目是存储在一个链接起来的列表的一个节点上,每个列表都是一个哈西表的元素。因此每个哈西表的条目(也叫一个桶-bucket)包含了一个链接起来的跟踪连接条目。 要访问一个特定包的跟踪连接条目,内核必须:
-针对一个包中的已经定义的一些字符计算哈西值。这是一个不间断的计算。
这个哈西值就会被当作哈西表的索引来使用,而跟踪连接条目的列表就存储在这里。
-反复的查看链接列表中的跟踪连接条目以找到匹配的那一个。
这是一个耗资源的操作,依赖于列表的大小(也依赖于列表中被操作的跟踪连接条目的位置)。
哈西表包含了HASHSIZE大小的链接条目。当条目满的时候(总的跟踪连接条目数达到了CONNTRACK_MAX),理想状态下,每个列表(bucket,在最优化的条件下)将包含大约CONNTRACK_MAX/HASHSIZE的条目数。
不管你是否有连接,哈西表都将占用一个固定大小的非交换内核内存。但是最大连接跟踪条目会检测最多可以存储多少条目(globally into the linked lists),也就是说他们最多可以占用多少的内核内存。
这篇文档将给你一些关于为了达到最好的netfilter conntracking/NAT系统性能,如何调优HASHSIZE和CONNTRACK_MAX值的提示。
CONNTRACK_MAX和HASHSIZE的默认值
=================================
一般来说,CONNTRACK_MAX和HASHSIZE都会设置在“合理”使用的值上,依据可
使用的RAM的大小来计算这个值。
CONNTRACK_MAX的默认值
——————————————-
在i386架构上,
CONNTRACK_MAX = RAMSIZE (以bytes记) / 16384 =
RAMSIZE (以MegaBytes记) * 64,
因此,一个32位的带512M内存的PC在默认情况下能够处理512*1024^2/16384 = 512*64 = 32768个并发的netfilter连接。
但是真正的公式是:
CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (x / 32)
这里x是指针的bit数,(例如,32或者64bit)
请注意:
-默认的CONNTRACK_MAX值不会低于128
-对于带有超过1G内存的系统,CONNTRACK_MAX的默认值会被限制在65536(即1024*64)(但是可以手工设置成更大的值)
HASHSIZE的默认值
—————————–
通常,
CONNTRACK_MAX = HASHSIZE * 8。这意味着每个链接的列表平均包含8个conntrack的条目(在优化的情况并且CONNTRACK_MAX达到的情况下),每个链接的列表就是一个哈西表条目(一个桶bucket)。
在i386架构上,HASHSIZE = CONNTRACK_MAX / 8 = RAMSIZE (以bytes记) / 131072 = RAMSIZE (以MegaBytes记) * 8。
举例来说,一个32位、带512M内存的PC可以存储512*1024^2/128/1024 = 512*8 = 4096 个桶(链接表)
但是真正的公式是:
HASHSIZE = CONNTRACK_MAX / 8 = RAMSIZE (以bytes记) / 131072 / (x / 32)
这里x是指针的bit数,(例如,32或者64bit)
请注意:
-默认HASHSIZE的值不会小于16
-对于带有超过1G内存的系统,HASHSIZE的默认值会被限制在8192(即1024*8)(但是可以手工设置成更大的值)
读取CONNTRACK_MAX和HASHSIZE
=============================
# cat /proc/sys/net/ipv4/ip_conntrack_max
# cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets注:以上2个文件,只有在iptables服务启动时才会存在。
修改CONNTRACK_MAX和HASHSIZE
=============================
默认的CONNTRACK_MAX和HASHSIZE的值都会因主机的不同而不同,但你可以在只做防火墙的高负载的系统上增加他们。
因此CONNTRACK_MAX和HASHSIZE值如果需要的话可以手工更改。
读取桶是一个连续性的操作(我们的兴趣在于得到一个哈西列表),请记得内核需要不停的遍历一个链接的列表去查找一个跟踪连接条目。因此一个链接列表(CONNTRACK_MAX/HASHSIZE的值在优化的状态下并且达到上限)的平均值不能设置太大。这个比值默认值是8(当值是自动计算的时候)。
在系统有足够的内存并且性能真的很重要的时候,你可以试着使平均值是一个跟踪连接条目配一个哈西桶,这意味着HASHSIZE = CONNTRACK_MAX。
设置CONNTRACK_MAX
————————————-
跟踪连接的条目是存储在链接的表中的,因此最大的跟踪链接条目(CONNTRACK_MAX)可以很容易的动态调整。
# echo $CONNTRACK_MAX > /proc/sys/net/ipv4/ip_conntrack_max
设置HASHSIZE
———————–
因为数学上的原因,哈西表占有固定的大小。因此HASHSIZE必须在哈西表被创建和开始填充之前就确定。
在linux内核2.4.21之前,必须使用素数作为哈西表的大小,而且要保证这个哈西表能够有效并通用。非素数的奇数或者其他的数值都是强烈不推荐使用的,因为这样哈西的分配不能达到最优化的状态。
从linux内核2.4.21(还有2.6内核)跟踪连接使用jenkins2b算法,这样就可以使用所有的数值,但是使用2^n次方运作的最有效。
如果netfilter的跟踪连接是被编译进内核中的,哈西表的大小就可以在编译的时候设置,或者(2.6内核之后)可以作为一个启动选项ip_conntrack.hashsize=$HASHSIZE。
如果netfilter的跟踪连接是编译成一个模块,哈西表的大小可以在加载模块的时候设置,使用下面的命令:
# modprobe ip_conntrack hashsize=$HASHSIZE
Since 2.6.14, it is possible to set hashsize dynamically at runtime,after boot and module load.
Between 2.6.14 and 2.6.19 (included), use:
# echo $HASHSIZE > /sys/module/ip_conntrack/parameters/hashsize
Since 2.6.20, use:
# echo $HASHSIZE > /sys/module/nf_conntrack/parameters/hashsize
============================================
============================================
23:09 2010-1-19 实际操作@RHEL4.6 by sealinger
修改方法(将 ip_conntrack_max 设置为 2^20,默认值是 2^16=65536)
# vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 1048576
修改 hashsize 大小:
# vi /etc/modprobe.conf
options ip_conntrack hashsize=131072
#
service iptables restart# cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets
131072
# tail /var/log/messages
Jan 19 18:46:36 nfs7 kernel: ip_tables: (C) 2000-2002 Netfilter core team
Jan 19 18:46:36 nfs7 kernel: ip_conntrack version 2.1 (131072 buckets, 1048576 max) – 340 bytes per conntrack
Jan 19 18:46:36 nfs7 iptables: succeeded
以后系统重启、iptables重启,都会自动生效。