NAS特定场景下buffered io比direct io读性能差问题的调查

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
日志服务 SLS,月写入数据量 50GB 1个月
简介: 最近一位NAS用户在微信上报道了NAS的性能测试报告,报告中测试数据显示buffered io读性能比direct io读要差。这显然和直观的认识不符,在内存充足的情况下,buffered io读的数据一般都在page cache中,每次读都是内存操作,其性能应该远远高于direct io,但测试.

最近一位NAS用户在微信上报道了NAS的性能测试报告,报告中测试数据显示buffered io读性能比direct io读要差。这显然和直观的认识不符,在内存充足的情况下,buffered io读的数据一般都在page cache中,每次读都是内存操作,其性能应该远远高于direct io,但测试数据却得到了相反的结果,这说明某些地方拖慢了buffered io读性能。

首先回顾一下用户的测试场景:保证内存完全够用的情况下,使用fio工具,基于libaio对比测试buffered io和direct io的读性能。结合测试场景和NAS后端逻辑可得到如下信息:

1) 内存完全够用,文件的数据能够全部缓存到内存中;

2) fio使用libaio库发起异步读请求(这通过阅读fio代码确认);

3) NAS后端在处理读请求时,不关心到底是buffered io还是direct io;

4) 挂载参数:vers=3,nolock,actimeo=0,proto=tcp,sec=sys,port=2049

基于上述信息,直观上推断可能是NFS客户端或者fio的实现导致测试数据异常,从该疑点出发,跟踪了客户端读操作的调用过程:

io_submit(系统调用) ---> io_submit_one(fs/aio.c) ---> aio_run_iocb(fs/aio.c) ---> aio_rw_vect_retry(fs/aio.c) ---> nfs_file_read(fs/nfs/file.c)

nfs_file_read的代码实现比较简单:


1) 针对O_DIRECT情况:

nfs_file_direct_read会在调用nfs_sync_mapping(因为是只读场景该函数不会触发sync操作)后调用nfs_direct_read_schedule_iovec,该函数会调用nfs_direct_read_schedule_segment对每个需要读取的数据片段发起异步的rpc请求操作,然后返回,不会有阻塞的情况发生;

2) 针对buffered io的情况:

首先会调用nfs_revalidate_mapping函数,当actimeo=0情况下会发起同步的getattr操作去更新inode信息这会导致io_submit系统调用阻塞,进而导致fio的压力线程阻塞住,对外看来就是只有一个并发在运行,其代码如下:



nfsv3协议中getattr函数调用的是nfs3_proc_getattr,在nfsv4调用的是nfs4_proc_getattr,以v3为例:


综合上面的代码分析可知,buffered io读性能差的原因是在actimo=0的情况下,内核每次读文件时都去server端获取inode最新的属性信息,以确保本地page cache数据的有效性,若inode信息表明文件内容没有改动,则直接使用page cache中缓存的数据给调用者;否则会在nfsi->cache_validity设置NFS_INO_INVALID_DATA标记,nfs_revalidate_mapping函数会调用nfs_invalid_mapping函数将page cache清空掉。当前nfs client判断page cache有效性主要通过ctimemtimechange time等属性是否发生变化判断。

为验证上述推断的正确性,进行了如下的对比测试:

1) mount参数不变,增加fioworker的数量(通过numjobs选项指定),发现在一定的范围内,性能随着numjobs的变大而基本呈现线性增加的趋势;

2)修改mount参数actimeo不为0,发现刚开始一段时间内qps没有什么太大变化依旧很慢,然后运行一段时间后突然飙升,直接上升到300K左右的QPS,后续继续测试同一文件QPS保持很高,基本不再变化,本地文件系统文件测试也存在同样的现象。

针对对比测试2)中的场景,跟踪了generic_file_aio_read的实现逻辑,其对每个需要读取的数据段调用do_generic_file_read,该函数的主要逻辑是从文件的page cache (文件的address space对象)中查找对应数据所在的page是否存在,若存在且page的数据是有效的(uptodate),则将数据拷贝到用户指定的buffer中;若不存在或者page中不是有效数据,则等待page的数据变为有效(必要时会发起预读操作)。从上述的分析可知,此时的buffered io读仍旧是同步的过程,即fio发起压力仍旧为同步的,所以测试用例刚开始运行时,性能依旧不高,随着page cache不断填充,当page cache接近完全命中时,QPS会有一个暴涨的过程。下面是,page cache命中率和QPS之间的关系图,其中page cache命中读延时为0.0033ms,不命中延时为1.5ms (采用NFSServerMock测试的数据)


从图中可知,随着page cache命中率的增高,QPS逐渐增加,但只有在命中率90%以上时,才有QPS的暴增过程,这是和实验结果相符的。

调查问题的过程中,查阅了一些linux内核aio的相关资料和实现,内核本身对direct io提供较好的支持,这也是大多数应用使用libaio的基本场景;但对于buffered io的支持是有限的,下面的文章对此进行了一些讨论:

http://www.wzxue.com/linux-kernel-aio%E8%BF%99%E4%B8%AA%E5%A5%87%E8%91%A9/#6_AIO

针对该用户性能测试遇到问题,解决的方法可在如下两个方面入手:

1) 若应用容忍短时间内多个NFS客户端存在不一致,则可将actimeo参数设定为非零值,避免每次操作都要去server端获取最新的inode等信息,提高性能;

2) 若应用不能容忍不一致的情况即actimeo=0,则最好使用direct io的方式,避免buffered io可能引发的阻塞操作。


最后附上用户的测试报告地址: http://mp.weixin.qq.com/s?__biz=MzAxNTA2NjkyNQ==&mid=2650380557&idx=1&sn=b7a3276c866b097a918ee1c91385b13b&scene=23&srcid=0502xGTLpNRsq5pIKxH2c5TY#rd

相关实践学习
基于ECS和NAS搭建个人网盘
本场景主要介绍如何基于ECS和NAS快速搭建个人网盘。
阿里云文件存储 NAS 使用教程
阿里云文件存储(Network Attached Storage,简称NAS)是面向阿里云ECS实例、HPC和Docker的文件存储服务,提供标准的文件访问协议,用户无需对现有应用做任何修改,即可使用具备无限容量及性能扩展、单一命名空间、多共享、高可靠和高可用等特性的分布式文件系统。 产品详情:https://www.aliyun.com/product/nas
目录
相关文章
|
8月前
|
缓存 监控 IDE
linux如何查看io性能
linux如何查看io性能
128 0
|
3月前
|
存储 缓存 算法
如何优化阻塞IO的性能?
【10月更文挑战第6天】如何优化阻塞IO的性能?
60 5
|
2月前
|
存储 弹性计算 固态存储
阿里云服务器ESSD Entry系统盘测评IOPS、IO读写和时延性能参数
ESSD Entry云盘是阿里云推出的新一代云盘,具备高IOPS、低延迟和企业级数据保护能力。适用于开发与测试场景,支持按量付费和包年包月计费模式。99元和199元的ECS经济型e实例和通用算力型u1实例均采用ESSD Entry系统盘,性价比高。详细性能参数和价格请参考阿里云官方页面。
94 0
|
3月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
72 2
|
5月前
|
存储 Java 数据库连接
BIO阻塞IO流与数据存储大揭秘:性能与资源消耗,一文让你彻底解锁!
【8月更文挑战第25天】本文探讨了Java中BIO阻塞IO流与数据存储的概念及其实现。BIO作为一种传统IO模型,在处理每个客户端请求时需创建新线程并等待响应,这在并发量大时会导致性能下降和高资源消耗。示例代码展示了如何利用`ServerSocket`实现基于BIO的简单服务器。此外,文章还介绍了数据存储的基本方法,例如通过`BufferedWriter`向文件写入数据。两者对比显示,BIO适合连接数稳定的场景,而数据存储则适用于需要持久化保存信息的情况。通过这些分析和实例,希望能帮助读者更好地掌握这两种技术的应用场景及其优缺点。
56 0
|
5月前
|
C# 开发者 设计模式
WPF开发者必读:命令模式应用秘籍,轻松简化UI与业务逻辑交互,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,命令模式是简化UI与业务逻辑交互的关键技术,通过将请求封装为对象,实现UI操作与业务逻辑分离,便于代码维护与扩展。本文介绍命令模式的概念及实现方法,包括使用`ICommand`接口、`RelayCommand`类及自定义命令等方式,并提供示例代码展示如何在项目中应用命令模式。
62 0
|
7月前
|
存储 文件存储
DAS和NAS的性能对比?
【6月更文挑战第29天】DAS和NAS的性能对比?
103 4
|
7月前
|
Java 测试技术
Java IO流深度剖析:字节流和字符流的性能对比!
【6月更文挑战第26天】Java IO流分字节流和字符流,字节流处理所有类型数据(如图片),字符流处理文本(基于Unicode)。字节流直接处理,性能高,适合非文本文件;字符流处理文本时考虑编码,适合文本文件。性能测试显示,字节流在读写非文本文件时更快,而字符流在处理文本时更方便。选择流类型应依据数据类型和需求。
88 0
|
7月前
|
调度 数据库 开发者
在Python编程中,并发编程和异步IO是两个重要的概念,它们对于提高程序性能和响应速度具有至关重要的作用
【6月更文挑战第10天】本文介绍了Python并发编程和异步IO,包括并发编程的基本概念如多线程、多进程和协程。线程和进程可通过threading及multiprocessing模块管理,但多线程受限于GIL。协程利用asyncio模块实现非阻塞IO,适合处理IO密集型任务。异步IO基于事件循环,能提高服务器并发处理能力,适用于网络编程和文件操作等场景。异步IO与多线程、多进程在不同任务中有各自优势,开发者应根据需求选择合适的技术。
53 0
|
存储 监控 安全
深聊性能测试,从入门到放弃之:如何对IO进行性能调优
深聊性能测试,从入门到放弃之:如何对IO进行性能调优
282 0

相关产品

  • 文件存储 NAS