lighty 的生活

lighty 开发者博客

Lighty 1.5.0 和 Linux-aio

1.5.0 版本将是所有用户的一大胜利。它在处理上将更灵活,并且由于异步 I/O,将对静态文件有巨大改进。

以下基准测试显示,新的 linux-aio-sendfile 后端相比经典的 linux-sendfile 后端,性能提升了 80%

测试环境是

  • 客户端: Mac Mini 1.2Ghz, MacOS X 10.4.8, 1Gb 内存, 100Mbit
  • 服务器: AMD64 3000+, 1Gb 内存, Linux 2.6.16.21-xen, 160Gb RAID1 (软 RAID)

服务器运行的是 lighttpd 1.4.13 和 lighttpd 1.5.0-svn,配置纯净 [未加载模块],客户端将使用 http_load。

客户端将运行


$ ./http_load -verbose -parallel 100 -fetches 10000 urls

我用这个小程序生成了 1000 个文件夹,每个文件夹包含 100 个 100KB 大小的文件。

for i in `seq 1 1000`; do 
  mkdir -p files-$i; 
  for j in `seq 1 100`; do 
    dd if=/dev/zero of=files-$i/$j bs=100k count=1 2> /dev/null; 
  done; 
done

这就是 10GB 的数据,是服务器内存大小的 10 倍,因为我们希望在磁盘上达到寻道瓶颈。

限制

两块希捷 Barracuda 160GB 硬盘 (ST3160827AS) 通过 linux-md 驱动构建 RAID1。7200 转/分钟将给我们带来最高 480 次寻道/秒 (7200 转/分钟 = 120 转/秒,每次寻道平均 0.5 转,2 块硬盘)。

每块硬盘可以进行 30MB/秒的顺序读取,合计 60MB。

网络是 100Mbit/秒,我们预计其上限为 10MB/秒。

lighttpd 1.4.13, sendfile

对 lighttpd 1.4.13 使用 linux-sendfile 的首次测试运行结果是

$ iostat 5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.99    0.00    4.77   86.68    0.20    7.36

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              35.19      3503.78       438.97      17624       2208
sdb              33.40      4052.49       438.97      20384       2208
md0             119.48      7518.09       429.42      37816       2160

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.60    0.00    4.61   78.36    0.00   16.43

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              31.46      3408.42       365.53      17008       1824
sdb              30.06      3313.83       365.53      16536       1824
md0             104.21      6760.72       357.52      33736       1784

http_load 返回


./http_load verbose -parallel 100 -fetches 10000 urls
-
- 60.006 secs, 1744 fetches started, 1644 completed, 100 current
- 120 secs, 3722 fetches started, 3622 completed, 100 current
- 180 secs, 5966 fetches started, 5866 completed, 100 current
- 240 secs, 8687 fetches started, 8587 completed, 100 current
10000 fetches, 100 max parallel, 1.024e+09 bytes, in 274.323 seconds
102400 mean bytes/connection
36.4534 fetches/sec, 3.73283e+06 bytes/sec
msecs/connect: 51.7815 mean, 147.412 max, 0.181 min
msecs/first-response: 360.689 mean, 6178.2 max, 1.08 min
HTTP response codes:
code 200 — 10000

lighttpd 1.5.0, sendfile

使用 lighttpd 1.5.0 和相同的网络后端:linux-sendfile 进行相同的测试。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.40    0.00    3.60   85.60    0.00   10.40

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              33.80      4606.40       564.80      23032       2824
sdb              37.00      4723.20       564.80      23616       2824
md0             136.00      9368.00       553.60      46840       2768

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.80    0.00    4.80   81.80    0.00   12.60

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              33.40      4198.40       504.00      20992       2520
sdb              30.60      4564.80       504.00      22824       2520
md0             123.60      8763.20       496.00      43816       2480

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.80    0.00    5.19   81.24    0.00   12.77

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              36.53      4490.22       493.41      22496       2472
sdb              32.34      4784.03       493.41      23968       2472
md0             126.75      9274.25       483.83      46464       2424

客户端显示


- 60 secs, 2444 fetches started, 2344 completed, 100 current
- 120.003 secs, 4957 fetches started, 4857 completed, 100 current
- 180 secs, 7359 fetches started, 7259 completed, 100 current
- 240 secs, 9726 fetches started, 9626 completed, 100 current
10000 fetches, 100 max parallel, 1.024e+09 bytes, in 246.803 seconds
102400 mean bytes/connection
40.5181 fetches/sec, 4.14906e+06 bytes/sec
msecs/connect: 55.5808 mean, 186.153 max, 0.24 min
msecs/first-response: 398.639 mean, 6101.44 max, 9.313 min
HTTP response codes:
code 200 — 10000

这只是稍微好一点,但仍然存在相同的问题。我们被磁盘而非网络限制了性能。

lighttpd 1.5.0, linux-aio-sendfile

我们只是将网络后端切换到异步 I/O 后端

server.network-backend = "linux-aio-sendfile"

……然后再次运行我们的基准测试

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.38    0.00   10.18   38.52    0.00   42.91

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              42.91      7190.42       526.95      36024       2640
sdb              36.93      6144.51       526.95      30784       2640
md0             205.99     13213.57       517.37      66200       2592

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.80    0.00    9.84   48.39    0.20   40.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              50.40      8369.48       573.49      41680       2856
sdb              44.18      7318.88       573.49      36448       2856
md0             241.77     15890.76       563.86      79136       2808

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.60    0.00    8.38   44.91    0.00   46.11

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              50.10      7580.04       720.16      37976       3608
sdb              47.50      7179.24       720.16      35968       3608
md0             242.12     14558.08       710.58      72936       3560

客户端显示

--- 60.0001 secs, 3792 fetches started, 3692 completed, 100 current
--- 120 secs, 8778 fetches started, 8678 completed, 100 current
10000 fetches, 100 max parallel, 1.024e+09 bytes, in 137.551 seconds
102400 mean bytes/connection
72.7004 fetches/sec, 7.44452e+06 bytes/sec
msecs/connect: 66.9088 mean, 197.157 max, 0.223 min
msecs/first-response: 226.181 mean, 6066.96 max, 2.098 min
HTTP response codes:
  code 200 -- 10000

总结

使用异步 I/O 允许 lighttpd 重叠文件操作。我们发送一个文件的 I/O 请求,并在文件准备好时收到通知。这样就无需等待文件 (像正常的 sendfile() 那样) 并阻塞服务器,我们可以转而处理其他请求。

另一方面,我们允许内核根据需要重新排序文件请求。

结合这两项改进,我们可以将吞吐量提高 80%

另一方面,lighty 本身不会花费任何时间在等待上。64 个内核线程在后台为我们处理 read() 调用,这将空闲时间从 12% 增加到 40%,提升了 230%

lighttpd

请注意,我们不接受发布超过 3 个月的文章的评论! 另请使用我们的 bug 追踪器报告 bug,并使用我们的 IRC 频道 #lighttpd@libera 进行聊天。

« Linux 上的异步 I/O linux AIO 和大文件 »