在前文《文件IO操作的一些最佳实践》中,我介绍了一些 Java 中常见的文件操作的接口,并且就 PageCache 和 DIrect IO 进行了探讨,最近封装了一个 Direct IO 的库,趁着这个机会,谈谈 Java 中 Direct IO 的意义,以及简单介绍下这个轮子。
这一整合将由名为 DirectIO 的新协议来实现。DirectIO:让 NetBackup 直通 SpanFSDirectIO 是 Cohesity 推出的全新增强型 OST 协议。 DirectIO 将为 NetBackup 用户解锁 Cohesity Data Cloud 的强大功能:兼容所有 DataProtect 和 NetBackup 应用程序。更快、更大规模的网络恢复。 DirectIO让 NetBackup 能直接写入 SpanFS,减少传统 OST 的中间流程。SpanFS支持 NFS、SMB、S3、DirectIO 等多协议访问,具备企业级可靠性与扩展性。 DirectIO 主要用例及初始版本这项新的整合把源自 NetBackup 的备份数据引入SpanFS。 这催生了新用例:备份到磁带网络保险库(Cyber vault)自定义 AI 项目高级安全(Advanced security):威胁扫描、威胁搜寻、数据分类DirectIO 初始版本功能亮点:SpanFS
PHP中DirectIO直操作文件扩展的使用 关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习。 测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/4.PHP中DirectIO直操作文件扩展的使用 php 参考文档: https://www.php.net/manual/zh/book.dio.php https://www.ibm.com/developerworks/cn/linux/l-cn-directio
nd); } static int write(FileDescriptor fd, ByteBuffer src, long position, boolean directIO ByteBuffer bb; if (directIO) { ... } else { bb = Util.getTemporaryDirectBuffer int n = writeFromNativeBuffer(fd, bb, position, directIO, alignment, nd); if (n > 0) { if (dst instanceof DirectBuffer) return readIntoNativeBuffer(fd, dst, position, directIO, alignment if (directIO) { ... } else { bb = Util.getTemporaryDirectBuffer(rem); } try {
这里涉及到几个基本指令:sendfile、aio和directio,它们均与本地文件的操作有关,接下来我们分别看看它的意义。 标记(BSD,linux)的使用,对应directio()这个系统调用。 通过directio可以指定限定的尺寸大小,对于超过此size的文件,将会使用directio(而不再使用sendfile)。 根据directio的设计初衷,它具备sendfile的基本原理,只是不使用内核cache,而是直接使用DMA,而且使用之后内存cache(页对齐部分)也将被释放。 当aio和sendfile都开启时,将会对那些size大于directio设定值的文件使用aio机制:即当小于directio设定值的文件将直接使用sendfile(aio不参与)。
今天主要是文件相关的一些处理操作,包括 DirectIO、文件缓存以及 sendfile 相关的配置。这三个配置中,大家应该会见过 sendfile ,但是另外两个就比较少见了。 directio 是不是看着很眼熟,没错,早前我们在 PHP 的小课堂文章中学习过。 directio 当读入长度大于等于指定 size 的文件时,开启 DirectIO 功能。 Solaris 系统开启使用 directio() 功能。 它在处理大文件时 directio 4m; 或者在 Linux 系统使用 aio 时比较有用。默认 off 。 directio_alignment 为 DirectIO 设置文件偏移量对齐。
静态大文件处理优化 directio: dirrectio size | off; 默认为off,配置上下文:http,server,location。首次在nginx 0.7.7版本中引入。 当我们配置size后,当文件大小超过size后,将启用对应系统的directio相关系统调用来对文件进行处理,这在nginx作为静态大文件下载服务时,非常有用。 示例: directio 4m; 在linux相关系统中,我们也可以使用aio指令来对大文件下载进行优化。 location /video/ { aio on; directio 512; output_buffers 1 128k;} 在Linux上,directio 在Linux上同时启用AIO和sendfile时,AIO用于大于或等于directio指令中指定的大小的文件,而sendfile用于较小的文件或禁用directio的文件。
= file->is_directio; if (! = file->is_directio; goto update; } /* file was changed */ = of->is_directio; if (! (NGX_LOG_ALERT, log, ngx_errno, ngx_directio_on_n " \"%V\" failed", name ); } else { of->is_directio = 1; } } } done:
打开直接IO [gpadmin@gp-master ~]$ gpconfig -c gp_backup_directIO -v on 查看是否被启用 gpconfig -s gp_backup_directIO 修改IO数据块大小 查看当前数据块大小: [gpadmin@gp-master ~]$ gpconfig -s gp_backup_directIO_read_chunk_mb Values on all segments are consistent GUC : gp_backup_directIO_read_chunk_mb Master value: 20 Segment value: 20 修改数据块为10MB: $ gpconfig -c gp_backup_directIO_read_chunk_mb -v 10 4.使用命名管道 如果Segment主机没有足够的本地磁盘空间来备份到文件
direct done drbdadm up $resource 注意: 1、dd 要使用关键字 oflag=direct 即写文件的时候忽略cache的影响;还有一个可选的关键字iflag=directio , 用来控制源文件和目标文件的读写方式为directio; 2、以上脚本是需要两个角色是secondary的时候进行测试; 3、测试完,在设定primary node 并挂载/dev/drbd0的时候会提示
*/ if (clcf->directio <= of.size) { /* * DIRECTIO is set on transfer only * to allow kernel to cache "moov" atom */ if (ngx_directio_on(of.fd) == NGX_FILE_ERROR " \"%s\" failed", path.data); } of.is_directio = 1; if (mp4) { mp4->file.directio = 1; } } /* 设置响应状态和相关响应头信息,然后将响应头发送给用户 */ r->headers_out.status = of.is_directio; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out)
次数限制策略,从现网监控来看由写冲突导致的失败比例极小: 图10 Prepare次数限制导致的失败监控 挑战2:基于机械盘的DirectIO 存储 我们在新架构上采用DirectIO的方案实现了一套保证数据安全落盘的存储组件,DirectIO方案与其他两种写盘方案的对比如表格11所示。 在DirectIO的4K块中引入BlockID,以支持文件的循环利用(不再删文件)。 图12 4K DirectIO BlockID 挑战3:复杂的现网场景 机械盘RaidCache RaidCache以电池作为后盾,可以在WriteBack模式下持有待写盘的数据批量写盘,以极大提升机械盘的写盘性能 小结 全新的内存云存储,通过精简的PLog as DB、分布式强一致性读写协议等一连串优化,在性能上得到显著提升;结合DirectIO存储系统、PLog全量对齐等,系统首次访问失败率指标下降一个量级。
Number of threads: 24 Initializing random number generator from current time Extra file open flags: directio Number of threads: 24 Initializing random number generator from current time Extra file open flags: directio Number of threads: 24 Initializing random number generator from current time Extra file open flags: directio Number of threads: 24 Initializing random number generator from current time Extra file open flags: directio Number of threads: 24 Initializing random number generator from current time Extra file open flags: directio
sendfile on|off;:启用sendfile系统调用来发送文件 aio on|off;:表示是否在FreeBSD或Linux系统上启用内核级别的异步I/O功能,与sendfile是互斥的 directio size|off;:在FreeBSD和Linux系统上使用O_DIRECT选项去读取文件,与sendfile互斥 directio_alignment size;:与directio配合,指定directio
sendfile调用的最大传输量为1MB tcp_nopush on; # 启用最小传输限制功能 aio on; # 启用异步传输 directio 5m; # 当文件大于5MB时以直接读取磁盘的方式读取文件 directio_alignment 4096; # 与磁盘的文件系统对齐 output_buffers sendfile调用的最大传输量为1MB tcp_nopush on; # 启用最小传输限制功能 aio on; # 启用异步传输 directio 5m; # 当文件大于5MB时以直接读取磁盘的方式读取文件 directio_alignment 4096; # 与磁盘的文件系统对齐 output_buffers
www.passmark.com/downloads/PerformanceTest_Windows_x86_V10.exe 系统+passmark版本 蓝屏报错 server2016/2019 petst10/petst11 DirectIo64 _legacy.sys+12c5 win10/win11/server2022 petst10 DirectIo64.sys+12cc win10/win11/server2022 petst11 DirectIo64
配置参数: 大文件设置深度为2,广度为10,每个文件夹下的文件数量为400,每个文件的大小为10M,采用10个线程并发,顺序选择文件,随机读写, DirectIO的形式处理1M的数据 小文件设置深度为2 ,广度为100,每个文件夹下的文件数量为20,每个文件的大小为4k,采用10个线程并发,顺序选择文件,随机读写, DirectIO的形式处理4k的数据 # 主机定义 hd=default,vdbench # 文件系统工作负载定义 fwd=default,operation=write,xfersize=1m,fileio=random,fileselect=sequential,openflags=directio
配置块:http、server、location # AIO 系统调用 # 语法:aio on | off; # 默认:aio off; # 配置块:http、server、location # directio # 语法:directio size | off; # 默认:directio off; # 配置块:http、server、location # directio_alignment # 语法:directio_alignment size; # 默认:directio_alignment 512; # 配置块:http、server、location # 打开文件缓存
如果是在 Linux 系统中,使用 AIO 需要同时开启 directio 配置项,并且 directio 的配置必须是 512 才有效,启用了 directio 会自动关闭 sendfile。
posix_fadvise() ... found checking for O_DIRECT ... found checking for F_NOCACHE ... not found checking for directio