DirectIO(O_DIRECT) 详解

DirectIO(O_DIRECT) 详解

什么是DirectIO

DirectIO也叫无缓冲IO,裸IO(rawIO),意思是使用无缓冲IO对文件进行读写,不会经过OS Cache。

通常,我们使用的文件流读取、内存映射都属于Cache IO,因为将数据写入文件,首先会写入cache,最终再落盘到IO device 或者称为 disk上。cache IO使得我们在写入、读取(预读取、顺序读取等特性)文件数据的时候,性能得以提升,能够从cache(内存)中读取数据。

直接IO,则是直接将数据写入文件、或者从文件中读取出来,绕过了cache,这使得看起来性能没那么好,但是,仔细分析,无论哪种IO方式,最终数据都必须落盘,而两种的区别在于有无OS cache。

OS cache提供的预读取、顺序读取等特性,这些特性并不适用于所有的场景,比如数据库,数据库通常都有自己的一套缓存机制,就像mysql的innodb存储引擎,它有自己的缓存页,有自己的落盘机制,如果不使用directIO,这明显就会存在双重的cache,一个是OS设计的,一个是DB设计的,而通常,DB需要更加符合自己使用的cache机制,而非OS提供的通用化的缓存机制。

如何使用DirectIO

使用直接IO进行数据的写入

//d io
#include <fcntl.h>
#include <malloc.h>
#include <iostream>
#define _GNU_SOURCE //测试宏

void rawIO() {
    int fd;
    size_t length;
    char *buf;
    length = getpagesize() * 1024*16;
    cout << "page size:" << getpagesize() << endl;
    fd = open("/home/out.log", O_RDWR | O_APPEND | O_DIRECT);//选用了centos系统作为实验平台
    if (fd == -1) {
        printf("%s", strerror(errno));
        exit(-1);
    }
    //函数:void * memalign (size_t boundary, size_t size)
    //函数memalign将分配一个由size指定大小,地址是boundary的倍数的内存块。参数boundary必须是2的幂!
    // 函数memalign可以分配较大的内存块,并且可以为返回的地址指定粒度。
    //函数:void * valloc (size_t size)
    //使用函数valloc与使用函数memalign类似,函数valloc的内部实现里,使用页的大小作为对齐长度,使用memalign来分配内存。它的实现如下所示:
    //void *
    //valloc (size_t size)
    //{
    //return memalign (getpagesize (), size);
    //}
    buf = (char *) memalign(getpagesize(), length);
    if (buf == nullptr) {
        printf("%s", strerror(errno));
        exit(1);
    }
    for (int i = 0; i < length; i++) {
        buf[i] = 'a';
    }
    int ret = write(fd, (void *) buf, length);
    if (ret == -1) {
        std::cout << "write fail" << std::endl;
        printf("%s \n", strerror(errno));
    }
    free(buf);
}

由于直接IO绕过了cache,因此,申请读写的buffer不能够使用malloc等函数,因为这些函数并不能够实现地址对齐,因此要使用memalign,这里注意,第一个参数必须对齐页大小,是页大小的幂次。

如果使用DIRECT IO进行读取,和写差不多,也要申请对齐的buf。

DirectIO的性能

为了测试直接IO的性能,这里使用常规的写(不手动落盘)、手动落盘、自动落盘、直接IO的耗时比较,测试变量:

写入:4096* 1024*16 字节的耗时如下:

raw IO elapse ms:862
raw IO elapse us:862723
cache IO 手动 elapse ms:908
cache IO 手动 elapse us:908871
cache IO 自动 elapse ms:885
cache IO 自动 elapse us:885480
cache IO elapse ms:297
cache IO elapse us:297153

可以看出,实际落盘的时间都是差不多的,而写OS Cache,在不立即落盘的情况下,是最快的。

DirectIO的应用

  • 数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值