由nginx工作进程导致的磁盘IO高得无法解决

我刚刚安装了一个Ubuntu 12.04.2 LTS服务器,服务于大量的非常大的静态文件。 configuration与其他机器上的configuration相同,效果很好。 另一台机器使用Ubuntu 11.10和nginx 1.0.5。 有问题的机器使用nginx 1.1.19,并且难以推动20MB / s左右(但在1Gbit专用线上),iotop显示nginx的高磁盘IO。 这是从iotop:

TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 4569 be/4 www-data 754.61 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process 4571 be/4 www-data 1257.69 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process 4574 be/4 www-data 2.46 M/s 0.00 B/s 0.00 % 99.99 % nginx: worker process 3951 be/4 www-data 1760.77 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 3950 be/4 www-data 503.08 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 4573 be/4 www-data 2012.31 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process 3952 be/4 www-data 1006.15 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 3954 be/4 www-data 1760.77 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 4572 be/4 www-data 4.05 M/s 0.00 B/s 0.00 % 99.99 % nginx: worker process 3956 be/4 www-data 2.70 M/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 3953 be/4 www-data 251.54 K/s 0.00 B/s 0.00 % 99.99 % nginx: worker process is shutting down 4567 be/4 www-data 2.21 M/s 0.00 B/s 0.00 % 98.30 % nginx: worker process 4570 be/4 www-data 754.61 K/s 0.00 B/s 0.00 % 97.91 % nginx: worker process 3949 be/4 www-data 1006.15 K/s 0.00 B/s 0.00 % 88.21 % nginx: worker process is shutting down 3955 be/4 www-data 1509.23 K/s 0.00 B/s 0.00 % 84.60 % nginx: worker process is shutting down 

因此,出于某种原因,那些试图closures的进程会导致IO和服务器进入一个几乎不响应的状态,负载增长高达5-6(这是一个双核心机器)。 同时CPU利用率大约是0.5%

重新启动nginx后,一切都很好,然后再次发生。

这是nginx错误日志中的最新内容:

 013/03/18 13:09:28 [alert] 3676#0: open socket #297 left in connection 145 

然后发生这种情况:

 2013/03/18 13:10:11 [alert] 3749#0: 100 worker_connections are not enough 

这是nginx.conf:

 user www-data; worker_processes 8; worker_rlimit_nofile 20480; pid /var/run/nginx.pid; events { worker_connections 100; # multi_accept on; } http { ## # Basic Settings ## sendfile off; output_buffers 1 512k; tcp_nopush on; tcp_nodelay on; keepalive_timeout 5; types_hash_max_size 2048; 

任何帮助将不胜感激!

编辑:

Sendfile打开和closures没有任何区别。

worker_rlimit_nofile == worker_connections没有区别。

worker_processes也没有改变。

smartctl显示磁盘没有问题,但是我尝试了在这台机器上的第二个磁盘,仍然没有区别。

相对较新的HDD在连续读取(和写入)时可以达到150MB / s(1.2Gbps),但是如果您有多个并行读取/写入(即使每个读取本身仍然是连续的),则吞吐速度将容易下降10倍。

所以, 20MB / s(160Mbps)听起来像是你的硬盘的限制

也许其他服务器有一个固态硬盘,或有更多的内存,并有这些文件caching,但这一个在caching方(错误的内存,但可能错误地优化内核设置)有问题。

无论如何,这可能听起来像是nginx控制之外的东西。

你可以尝试增加你的nginx内存缓冲区数倍,以便使读取更顺序一些,但是如果你只有一个基于盘片的硬盘驱动器(例如,单次顺序读取时最多150MB / s,在多次读取时会出现几次折叠),并且由于内存不足而无法使用caching,那么您将无法在接近1Gbps(128MB / s)的任何位置进行推送。

如果你真的需要1Gbps的吞吐量:如果大部分常见的文件可以caching在内存中,获得更多的内存; 否则,得到一个快速的SSD。

我会打开sendfile

  sendfile on 

我认为这样可以避免不必要的复制并保存系统调用。 另外,tcp_nopush只会在sendfile打开时打开。 看这里。

另外, 删除types_hash_max_size。