`
fp_moon
  • 浏览: 978244 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

如何调优HASHSIZE和CONNTRACK_MAX值

 
阅读更多
如何调优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 / 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)。


这样,你可以存储默认值32倍的跟踪连接条目,而且可以得到更好的跟踪连接性能。
分享到:
评论

相关推荐

    iptables的conntrack表满了导致访问网站很慢.docx

    在i386架构上,可以在`/etc/modprobe.conf`文件中设置`options ip_conntrack hashsize=131072`。这个值的增大有助于减少冲突,提高查找速度。 完成参数修改后,需要重启iptables服务以使新配置生效,如`# service ...

    数据结构散列表电话号码查询系统课程设计

    在设计过程中,我们还探索了如何优化散列函数和冲突处理策略,以提高系统的整体性能。此外,该项目还加深了我们对 C 语言的理解,尤其是在函数定义和调用方面的实践能力。 #### 五、附件:部分源程序代码 这里展示...

    GBase-8s数据库管理员技术参考-D.docx

    - **格式**:文件中的每一行代表一个配置项,格式为“名称=值”。例如,“BUFFERPOOL=200M”。 **2.1.2 onconfig门户:按功能性类别划分配置参数** - **概述**:`onconfig` 文件中的参数按照其功能特性被划分为...

    数据结构课程设计散列表电话号码查询系统

    散列函数`Hash1(NA str)`将姓名字符串转化为一个介于0和`HASHSIZE - 1`之间的整数,这个整数就是存储该信息的位置。这里`HASHSIZE`被定义为53,这是为了平衡散列冲突的可能性和内存利用率。当多个键映射到同一位置时...

    VS2010求取MD5值 实例源码

    总之,这个"VS2010求取MD5值 实例源码"提供了学习和实践C++计算MD5值的机会,对于初学者来说,通过调试和阅读代码,可以加深对MD5算法和Windows API的理解。同时,这样的工具函数在软件开发中非常实用,例如在文件...

    glusterfs的那些事-3.4.51

    2. **哈希表大小**:`dentry_hashsize`和`inode_hashsize`分别表示dentry(目录项)和inode的哈希表大小,用于快速查找和定位文件或目录。 3. **名称指针**:`name`字段通常与根目录相关联。 4. **inode链表**:`...

    . In hash table, to complete the code for Insert_Hash,

    2. **HashFun** 函数:这是一个简单的哈希函数,它接收员工的ID作为参数,然后返回一个介于0和HASHSIZE-1之间的值,作为哈希表的下标。在这个例子中,采用的是取模运算(%)作为哈希函数,这是一种常见的简单哈希...

    右移位是带符号的还是无符号的.docx

    此时,我们可以确保h在0到HASHSIZE之间,通过添加一个检查和修正,如:h = n % HASHSIZE; if (n ) h += HASHSIZE; 或者将n声明为无符号类型,这样可以避免负数的问题。 总之,右移位操作在C语言中对有符号和无符号...

    hash函数 实例

    哈希函数用于计算输入值的哈希地址,即根据员工的 ID 计算其在哈希表中的位置。 ```c int HashFun(int key) { return key % HASHSIZE; } ``` 这里采用了取模运算,即将员工 ID 对 `HASHSIZE` 取模得到其在哈希表中...

    数据结构课程设计_哈希表实验报告.doc

    - **除留余数法**:哈希函数`Hash1`利用折叠处理后的名字的总和对哈希表大小(`HASHSIZE`)取模,得到哈希值。 4. **冲突处理**: - **线性探测再散列**:当多个关键字映射到同一个位置时,会产生冲突。此处采用...

    数据结构课程设计源代码

    它可能包含计算哈希值、处理冲突和在适当位置插入新元素的步骤。 8. **状态枚举(Status)**:源代码中定义了一些枚举常量,如`OK`、`ERROR`和`SUCCESS`,用于表示操作的结果。这有助于提高代码的可读性和错误处理...

    c语言hash table的实现

    具体实现时,通过位运算和字符串长度计算出一个唯一的哈希值,确保不同字符串尽可能映射到不同的位置上。 ```c unsigned int lh_strhash(void* src) { int i, l; unsigned long ret = 0; unsigned short* s; ...

    哈希表实现

    - `unsigned int hash(char *s)`函数实现了一个简单的哈希算法,通过累加字符串中每个字符的ASCII值并乘以31来计算哈希值,最后对`HASHSIZE`取模得到最终的索引位置。 4. **查找操作**: - `node* lookup(char *n...

    数据结构课程设计报告模板(参考).docx

    该系统包括了用户信息的添加、读取、以姓名和电话号码建立哈希表、查找并显示给定用户名和电话号码的记录等功能。 系统功能设计 系统功能设计部分定义了系统的功能需求,包括了电话本记录数量、表长、姓名长度等...

    广工数据结构实验报告

    ` 用于计算关键字的哈希值。 - **异常处理函数**: 定义了一个碰撞处理函数 `voidcollision(int& hashValue, int hashSize);` 用于处理哈希冲突。 - **质数列表**: 定义了一个函数 `intstl_next_primes(int n);` ...

    哈希算法 员工信息插入,搜索,查找等操作

    这里采用的是简单的模运算,即`key%HASHSIZE`,这确保了即使ID的数值很大,也能均匀地分布在哈希表的各个位置上。 #### 三、哈希冲突处理 哈希冲突指的是不同的键被哈希函数映射到了同一个位置上。在代码中,冲突...

    sha.rar_加密解密_Visual_C++_

    在上述代码中,我们分别展示了如何使用CryptoAPI和Boost库计算SHA-256散列值。对于给定的"sha.rar"文件,我们可以读取其内容,然后调用上述函数进行散列计算,得到的数据可以作为消息的唯一标识,用于验证文件是否被...

    查 找 算 法 的 实 现.docx

    - **静态查找和动态查找**:理解这两种查找方式的基本概念和应用场景。 - **C语言实现**:掌握如何在C语言环境中实现静态查找算法操作。 - **哈希表的构建与查找**:学习如何构建哈希表以及如何使用开放地址法来处理...

    河南工业大学实验报告_实验三查找和排序(一)——查找.pdf

    "哈希表查找和冲突解决方法" 本实验报告主要介绍了哈希表的基本概念、哈希函数的应用、哈希表的建立、冲突解决方法和哈希查找算法的实现。通过本实验,学生可以掌握哈希函数的应用、哈希表的建立和冲突解决方法,...

    哈希表的实现

    - **哈希表结构**:定义了一个`HashTable`结构体,包含指针数组`elem`、当前元素数量`count`以及最大容量`hashsize`。 #### 源代码解析 - **哈希函数** (`Hash`): 根据提供的键值计算哈希地址。 - **判断空位** (`...

Global site tag (gtag.js) - Google Analytics