linux aio mysql_Linux Native AIO用法

异步I/O(AIO,asynchronous I/O),顾名思义,就是异步操作I/O。不像read/write那样会阻塞进程,必须等待其返回才能继续执行其它指令。

对于I/O密集性应用(如传统关系型数据库)异步I/O可以带来很大的性能提升。MySQL和Nginx已支持Native AIO。

1. 接口

linux native aio对使用O_DIRECT标识打开的文件会造成如下限制(如果无O_DIRECT标识,在调用io_submit时,会同步完成IO操作):AIO方式读写文件时,无法利用操作系统对文件的缓存,只能从磁盘读写

读写缓冲区的地址、内容的大小、文件偏移必须是扇区的倍数(通常是512字节)

2. 示例

#include#include#include#include#include#include#include

#define FILEPATH "./test.txt"

int main()

{

io_context_t context;

struct iocb io[2], *p[2]={&io[0], &io[1]};

struct io_event e[2];

unsigned nr_events = 10;

struct timespec timeout;

timeout.tv_sec = 0;

timeout.tv_nsec = 10000000;

char *wbuf = 0, *rbuf = 0;

int wbuflen = 512*1024*1024;

int rbuflen = wbuflen+1;

posix_memalign((void**)&wbuf, 512, wbuflen);

posix_memalign((void**)&rbuf, 512, rbuflen);

memset(wbuf, 'a', wbuflen);

memset(rbuf, 0, rbuflen);

memset(&context, 0, sizeof(io_context_t));

int ret = 0, comp_num = 0, i = 0;

int fd = open(FILEPATH, O_CREAT|O_RDWR|O_DIRECT, 0644);

if(fd < 0)

{

printf("open file failed !\n");

return 0;

}

if( 0 != io_setup(nr_events, &context) ){

printf("io_setup error:%d\n", errno);

}

io_prep_pwrite(&io[0], fd, wbuf, wbuflen, 0);

io_prep_pread(&io[1], fd, rbuf, rbuflen-1, 0);

if((ret = io_submit(context,2,p)) != 2)

{

printf("io_submit error:%d\n", ret);

io_destroy(context);

return -1;

}

while(true)

{

ret = io_getevents(context,2,2,e,&timeout);

if(ret < 0)

{

printf("io_getevents error:%d\n", ret);

break;

}

if(ret > 0)

{

comp_num += ret;

for( i = 0;i < ret; ++i)

{

printf("result,res2:%d, res:%d\n", e[i].res2, e[i].res);

}

}

if(comp_num >= 2)

{

printf("done !\n");

break;

}

printf("have not done !\n");

}

return 0;

}

3. AIO与epoll

在使用AIO时,需要通过系统调用io_getevents获取已经完成的IO事件,而系统调用io_getevents是阻塞的,所以有2种方式:

(1) 使用多线程,用专门的线程调用io_getevents,参考MySQL5.5及以上版本;

(2) 对于单线程程序,可以通过epoll来使用AIO;但需要系统调用eventfd的支持,在2.6.22之后的内核才支持。

eventfd 是 Linux-native aio 其中的一个 API,用来生成 file descriptors,这些 file descriptors 可为应用程序提供更高效 “等待/通知” 的事件机制。和 pipe 作用相似,但比 pipe 更好,一方面它只用到一个 file descriptor(pipe 要用两个),节省了内核资源;另一方面,eventfd 的缓冲区管理要简单得多,pipe 需要不定长的缓冲区,而 eventfd 全部缓冲只有定长 8 bytes。

关于AIO与epoll的结合可以参考nginx 0.8.x稳定版对linux aio的支持。

4. AIO与Direct IO

AIO需要与direct IO结合(为什么需要这样结合?)。Direct IO是数据直接在用户地址空间的缓冲区和磁盘之间直接进行传输,完全不需要页缓存的支持。

Direct IO读写操作都有硬性的要求,所有操作系统都一致:数据传输的开始点,即文件和设备的偏移量,必须是扇区大小的整数倍

待传递数据的长度必须是扇区大小的整数倍

用于传递数据的缓冲区,其内存边界必须对齐为扇区大小的整数倍

前两个限制就是为了保证读写的都是一个个完整的扇区。第一个限制要求从一个扇区的开始读写,第二个限制要求正好到一个扇区完截止。第三个限制则是为了保证读写一个扇区时不发生页错误(page fault)。

5. 参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值