参考文章:Nginx 万兆网络环境测试
上周在proxy层测试url hash万兆网卡服务器过程中发现服务器内存用满,使用大量的swap,导致服务器无响应。
一、 现象描述:
- swap 100%,IO超过60%;
- nginx每进程占用内存达4G,且无法释放内存,最终nginx出现内存无法分配报错;
- 服务器无响应;
- dmesg、message报错如下:
May 6 15:04:13 Cangke_107_176 kernel: nginx: page allocation failure. order:0, mode:0x20
May 6 15:04:13 Cangke_107_176 kernel: Pid: 8888, comm: nginx Not tainted 2.6.32-358.el6.x86_64 #1
May 6 15:04:13 Cangke_107_176 kernel: Call Trace:
May 6 15:04:13 Cangke_107_176 kernel: <IRQ> [<ffffffff8112c127>] ? __alloc_pages_nodemask+0x757/0x8d0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff811669d2>] ? kmem_getpages+0x62/0x170
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff811675ea>] ? fallback_alloc+0x1ba/0x270
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8116703f>] ? cache_grow+0x2cf/0x320
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81167369>] ? ____cache_alloc_node+0x99/0x160
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffffa0139aa8>] ? bnx2x_rx_int+0x228/0x1530 [bnx2x]
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81168139>] ? __kmalloc+0x189/0x220
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffffa0139aa8>] ? bnx2x_rx_int+0x228/0x1530 [bnx2x]
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8143d06b>] ? consume_skb+0x3b/0x80
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81448fbd>] ? dev_kfree_skb_any+0x3d/0x50
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8128d150>] ? swiotlb_map_page+0x0/0x100
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffffa013ae5b>] ? bnx2x_poll+0xab/0x2e0 [bnx2x]
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8144cd43>] ? net_rx_action+0x103/0x2f0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81076fb1>] ? __do_softirq+0xc1/0x1e0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8100c1cc>] ? call_softirq+0x1c/0x30
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8100c1cc>] ? call_softirq+0x1c/0x30
May 6 15:04:13 Cangke_107_176 kernel: <EOI> [<ffffffff8100de05>] ? do_softirq+0x65/0xa0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff810778fa>] ? local_bh_enable_ip+0x9a/0xb0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff815101ab>] ? _spin_unlock_bh+0x1b/0x20
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81438c7e>] ? release_sock+0xce/0xe0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8148ee61>] ? tcp_recvmsg+0x821/0xe80
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8148507c>] ? ip_finish_output+0x13c/0x310
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff814af6ca>] ? inet_recvmsg+0x5a/0x90
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8127d95c>] ? rb_erase+0x1bc/0x310
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81437473>] ? sock_recvmsg+0x133/0x160
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81096c80>] ? autoremove_wake_function+0x0/0x40
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8100988e>] ? __switch_to+0x26e/0x320
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff811c2d42>] ? fsnotify_clear_marks_by_inode+0x32/0xf0
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81433b69>] ? sock_destroy_inode+0x19/0x20
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff814375ee>] ? sys_recvfrom+0xee/0x180
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff811a1ae0>] ? mntput_no_expire+0x30/0x110
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff811827f1>] ? __fput+0x1a1/0x210
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff81182885>] ? fput+0x25/0x30
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8117dcdd>] ? filp_close+0x5d/0x90
May 6 15:04:13 Cangke_107_176 kernel: [<ffffffff8100b072>] ? system_call_fastpath+0x16/0x1b
===========================================================================
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
May 6 15:04:13 Cangke_107_176 kernel: bnx2x: [bnx2x_alloc_rx_sge:420(em2)]Can’t alloc sge
===========================================================================
5、sar信息收集
CPU:
sar -f sa06 | grep “CPU|^03:0″ | grep “PM|CPU”
Linux 2.6.32-358.el6.x86_64 (Cangke_107_1) 05/06/2014 _x86_64_ (24 CPU)
12:00:01 AM CPU %user %nice %system %iowait %steal %idle
03:00:01 PM all 5.00 0.00 5.87 0.00 0.00 89.12
03:01:01 PM all 5.37 0.00 8.35 0.01 0.00 86.27
03:02:03 PM all 5.24 0.00 7.93 11.12 0.00 75.71
03:03:01 PM all 7.45 0.00 5.71 32.00 0.00 54.84
03:04:16 PM all 5.93 0.00 7.12 37.88 0.00 49.07
03:05:03 PM all 0.56 0.00 1.45 64.94 0.00 33.05
03:06:05 PM all 2.07 0.00 2.64 57.55 0.00 37.75
03:07:01 PM all 2.75 0.00 3.52 46.32 0.00 47.41
03:08:01 PM all 3.88 0.00 4.36 2.40 0.00 89.36
03:09:01 PM all 3.83 0.00 4.40 0.69 0.00 91.09
SWAP:
sar -S -f sa06 | grep “free|^03:0″ | grep “PM|free”
12:00:01 AM kbswpfree kbswpused %swpused kbswpcad %swpcad
03:00:01 PM 8388600 0 0.00 0 0.00
03:01:01 PM 8388600 0 0.00 0 0.00
03:02:03 PM 5065192 3323408 39.62 107908 3.25
03:03:01 PM 4174996 4213604 50.23 745556 17.69
03:04:16 PM 1722900 6665700 79.46 120032 1.80
03:05:03 PM 423364 7965236 94.95 292404 3.67
03:06:05 PM 187788 8200812 97.76 713720 8.70
03:07:01 PM 726948 7661652 91.33 1034536 13.50
03:08:01 PM 814704 7573896 90.29 1160704 15.33
03:09:01 PM 848800 7539800 89.88 1216656 16.14
二、 测试服务器硬/软件:
Product Name: PowerEdge R620
CPU:Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz
Memory:32GB 8*4
Web server:nginx version: nginx/1.4.4
三、 测试压力需求:
1、 3000 qps
2、 26Mbytes 唯一图片文件
四、 判断问题:
1、 nginx在proxy模式时,虽然是同一张图片,但进程间缓存的内存数据无法共享;
2、 proxy_buffer_size及proxy_buffers开得太大,proxy buffer是对每个connection独立分配,连接数多、文件大,可能导致内存溢出;
proxy_buffer_size 128k;
proxy_buffers 1024 256k;
五、 测试解决问题过程:
1、 nginx开启proxy cache缓存文件,或文件真实存在是否会有内存溢出的现象?
测试结论:可打满万兆带宽,无压力;
2、 nginx关闭proxy_buffering,proxy_buffering off。处于http层纯透明模式是否会发生内存溢出现象?
测试结论:可打满万兆带宽,无压力;
3、 调整proxy_buffer_size,proxy_buffers参数,每个connection只维护一个较小的数据缓冲区,是否会发生内存溢出的现象?
proxy_buffer_size 32k;
proxy_buffers 16 32k;
测试结论:可打满万兆带宽,无压力;
六、 思考、优化:
图1:
1、 关闭proxy_buffering可以解决内存溢出的问题,但是纯透明代理模式会降低cache层的效率,用户的连接保持完全转嫁给cache层,可能同时给proxy和cache两层巨大的负担;
2、 统计后端所有对象的大小,综合考虑每台proxy需要handle多少的connection,给proxy_buffers分配一个合理的值;
3、 开启proxy_max_temp_file_size和proxy_temp_file_write_size,将超出buffers的数据写入硬盘是一个好想法,但是会带来IO的巨大负担,可以进行一个测试。(估计采购SSD备用)
转载请注明:爱开源 » 万兆网络环境下的nginx压力测试 (二)