背景
今晚数据库服务器收到到告警3306端口不通,登上服务器查看mysql进程正常,通过客户端也能正常连接,但是keepalived 一直检测说3306端口不通
检测日志/var/log/messages发现一直在打印”nf_conntrack: table full, dropping packet.”
通过网络查找资料,找到问题所在,
问题分析:
究其原因:nf_conntrack是一个内核模块,用于跟踪一个连接状态。连接跟踪状态可以供其他模块使用,例如state等,可通过以下查看
nf_conntrack模块会使用一个哈希表记录 tcp 通讯协议的 established connection记录,
当有大量的网站访问时,若iptables记录连接跟踪状态,就可能导出现“nf_conntrack:table full”,从而导致一系列问题。
处理办法:
关闭防火墙。 简单粗暴,直接有效
chkconfig iptables off chkconfig ip6tables off service iptables stop service ip6tables stop
切记:在防火墙关闭状态下,不要通过iptables指令(比如 iptables -nL)来查看当前状态!因为这样会导致防火墙被启动,而且规则为空。虽然不会有任何拦截效果,但所有连接状态都会被记录,浪费资源且影响性能并可能导致防火墙主动丢包!
加大防火墙跟踪表的大小,优化对应的系统参数
1、状态跟踪表的最大行数的设定
理论最大值 CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32) 以64G的64位操作系统为例,CONNTRACK_MAX = 64*1024*1024*1024/16384/2 = 2097152 即时生效请执行: sysctl -w net.netfilter.nf_conntrack_max=2097152 永久生效修改:/etc/sysctl.conf
2、设置跟踪连接保存5小时。
net.netfilter.nf_conntrack_tcp_timeout_established = 300
3、设置其哈希表大小
哈希表大小通常为总表的1/8,最大为1/2。CONNTRACK_BUCKETS = CONNTRACK_MAX / 8 同样64G的64位操作系统,哈希最佳范围是 262144 ~ 1048576 。 运行状态中通过 sysctl net.netfilter.nf_conntrack_buckets 进行查看,通过文件 /sys/module/nf_conntrack/parameters/hashsize 进行设置 或者新建 /etc/modprobe.d/iptables.conf ,重新加载模块才生效: options nf_conntrack hashsize=262144
扩展
还有些相关的系统参数sysctl -a | grep nf_conntrack
可以调优(/etc/sysctl.conf ):
net.netfilter.nf_conntrack_max = 1048576 net.netfilter.ip_conntrack_tcp_timeout_established = 3600 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120