谈谈异步IO(AIO)

对于类似ligthy的事件(event)驱动的server,某个阻塞操作会大大降低程序的效率。文件读取操作通常是最容易堵塞的地方;而异步IO(AIO)貌似是解决文件堵塞的灵丹妙药。

大概三个月前,花了点时间在lighttpd 1.4.18上实现了AIO的支持,也是了结一个心病。由于原来的LINUX AIO计划早已停止,我拿POSIX AIO for LINUX 做实验平台,补丁也移植到比较新的2.6.23上。

拿ab测试,发现AIO的大文件吞吐性能很差,不到linux sendfile的一半,系统负载却大很多;让人感觉不可思议,怎么会这样呢?印象中lighty 1.5的aio测试效果还不错的。仔细拜读lighty 1.5的aio 代码,才恍然大悟:

1) AIO不支持sendfile。纯AIO实现 需要把文件内容读到内存中,然后再写到网络层上。为了不占用大量内存,一般是按1M或几M大小依次读取文件内容。AIO可以在读取完毕后通知服务程序,避免阻塞;但内容读取到用户内存中再写到网络层的效率很低

2) Lighty 1.5为解决上面的问题采取了两个办法,第一是多线程;第二是不到万不得已的情况不用AIO,大部分是用mmap/sendfile的。

再拜读Posix AIO规范说明,发现AIO原本意图是解决实时系统中文件操作堵塞的问题。实时系统中文件一般不大,文件操作也不频繁,AIO就比较合适。而在web服务中,适合AIO的前提条件并不存在,因此效果不佳也正常。POSIX AIO定义的操作也不多

最后写三点感想:
1) 完成某个工作的,可以用到的工具(开源项目)很多,选择时要对备选的工具多考察,选择最适合的,而不是看起来最美的
2) 功能不是越多越好,保持代码简洁、系统框架简洁很重要。比如我个人认为ligthy 1.5中引入glib库是个败笔
3) sendfile 很好。对它的多年优化工作可不是白费的

Keywords: , ,


5 Responses to “谈谈异步IO(AIO)”  

  1. 1 druggo

    仅用做图片服务器的话,aio应该效果还不错的吧?

  2. 2 Q

    AIO做小图片的效率也不大行

    小图片要缓存到内存中,服务速度才快

  3. 3 j

    小图片,内存缓冲,aio,kqueue,FreeBSD 4.11:

    并发16000个连接
    每秒请求数4300

    升级到6之后性能一下掉了很多。

  4. 4 j

    忘记说了:内存缓冲 = 140G mmap()
    kqueue的EV_DISABLE要好好用。

  5. 5 Q

    曾经把RHEL 4.4的2.6.9-42 Kernel升级到最新的2.6.23,系统iowait增加100%以上。最新的不一定是最好的,适合自己的才是最好的

Leave a Reply



天气信息