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(可是能够手工设置成更大的值)
HASHSIZE的默认值
-------------------------
一般,CONNTRACK_MAX = HASHSIZE * 8。这意味着每一个连接的列表平均包含8个conntrack的条目(在优化的状况而且CONNTRACK_MAX达到的状况下),每一个连接的列表就是一个哈西表条目(一个桶)。
在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(可是能够手工设置成更大的值)
读取CONNTRACK_MAX和HASHSIZE
==================================
如今经过/proc文件系统咱们能够在运行时读取CONNTRACK_MAX的值。
在Linux kernel 2.4.23版本前,使用:
# cat /proc/sys/net/ipv4/ip_conntrack_max
在Linux kernel 2.4.23版本后,使用:
# cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max
(旧的 /proc/sys/net/ipv4/ip_conntrack_max是不建议使用的!)
当前的HASHSIZE老是能够在syslog信息中找到(对任何一个内核版本),桶(也就是HASHSIZE)的数目是在ip_conntrack初始化的时候显示出来的。
对于linux内核2.4.24之后,当前的HASHSIZE值能够在运行时使用下面的命令读取:
# cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets
修改CONNTRACK_MAX和HASHSIZE
====================================
默认的CONNTRACK_MAX和HASHSIZE的值都会因主机的不一样而不一样,但你能够在只作防火墙的高负载的系统上增长他们。
所以CONNTRACK_MAX和HASHSIZE值若是须要的话能够手工更改。
读取桶是一个连续性的操做(咱们的兴趣在于获得一个哈西列表),请记得内核须要不停的遍历一个连接的列表去查找一个跟踪链接条目。所以一个连接列表(CONNTRACK_MAX/HASHSIZE的值在优化的状态下而且达到上限)的平均值不能设置太大。这个比值默认值是8(当值是自动计算的时候)。
在系统有足够的内存而且性能真的很重要的时候,你能够试着使平均值是一个跟踪链接条目配一个哈西桶,这意味着HASHSIZE = CONNTRACK_MAX。
设置CONNTRACK_MAX
---------------------
跟踪链接的条目是存储在连接的表中的,所以最大的跟踪连接条目(CONNTRACK_MAX)能够很容易的动态调整。
linux内核2.4.23以前,使用:
# echo $CONNTRACK_MAX > /proc/sys/net/ipv4/ip_conntrack_max
linux内核2.4.23以后,使用:
# echo $CONNTRACK_MAX > /proc/sys/net/ipv4/netfilter/ip_conntrack_max
这里$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
这里$HASHSIZE是一个整数。
一个理想的例子:只作防火墙的机器
------------------------------------
在理想的例子中,你有一台机器只作包过滤和NAT(也就是说,基本上没有用户空间的使用,至少不会有象代理这样会不断的耗费内存空间的东西......)
netfilter跟踪链接使用的内核内存大小是:
size_of_mem_used_by_conntrack (以bytes记) =
CONNTRACK_MAX * sizeof(struct ip_conntrack) +
HASHSIZE * sizeof(struct list_head)
-这里:sizeof(struct ip_conntrack)能够有很大的区别,依赖于机器的体系架构,内核版本和编译时间的配置。要想知道它的大小,能够查看ip_conntrack初始化时候kenel的日志信息。sizeof(struct ip_conntrack)在i386架构、2.6.5内核上大约是300bytes,可是在2.6.10的内核上,这个值能够在352至192bytes之间变化!
-sizeof(struct list_head) = 2 * size_of_a_pointer
在i386上,size_of_a_pointer是4bytes。
所以在i386,2.6.5内核上,size_of_mem_used_by_conntrack大约是CONNTRACK_MAX * 300 + HASHSIZE * 8 (bytes)。
若是咱们使HASHSIZE = CONNTRACK_MAX(若是咱们将大部分的内存用来作防火墙的工做,参见“修改CONNTRACK_MAX和HASHSIZE”部分),在i386架构、2.6.5内核上,size_of_mem_used_by_conntrack大概是CONNTRACK_MAX * 308 bytes。
如今咱们假定你使用512M的内存拿来作一个只作防火墙的机器,而且使用128MB之外的内存来作跟踪链接,对于使用终端模式只作防火墙来讲应该是足够的大的,例如:
你能够同时设置CONNTRACK_MAX和HASHSIZE大体以下:
(512 - 128) * 1024^2 / 308 =~ 1307315 (instead of 32768 for CONNTRACK_MAX,
and 4096 for HASHSIZE by default)。
对于linux2.4.21(和linux2.6),哈西算法最好使用“2的次方”大小(以前是使用素数)。
所以在这里咱们能够将CONNTRACK_MAX和HASHSIZE设置成1048576(2^20)。html
转自:http://blog.sina.com.cn/s/blog_4078ccd601012crx.htmllinux