如何調優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(可是能夠手工設置成更大的值)

HASHSIZE的默認值
-------------------------

一般,CONNTRACK_MAX HASHSIZE 8。這意味着每一個連接的列表平均包含8個conntrack的條目(在優化的狀況而且CONNTRACK_MAX達到的狀況下),每一個連接的列表就是一個哈西表條目(一個桶)。

在i386架構上,HASHSIZE CONNTRACK_MAX =
RAMSIZE (以bytes記) 131072 RAMSIZE (以MegaBytes記) 8。
舉例來講,一個32位、帶512M內存的PC能夠存儲512*1024^2/128/1024 =
512*8 4096 個桶(連接表)

可是真正的公式是:
HASHSIZE CONNTRACK_MAX 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) size_of_a_pointer
  在i386上,size_of_a_pointer是4bytes。


所以在i386,2.6.5內核上,size_of_mem_used_by_conntrack大約是CONNTRACK_MAX 300 HASHSIZE (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

相關文章
相關標籤/搜索