问题
周日在Linux下搬运c盘数据,发觉一个很奇怪的现象。从通过ntfs-3g挂载的NTFS分区读取数据,写入到另外一个基于RAID1阵列的分区,理论上能到50MB/s+,实际上却只有20MB/s左右。并且在Windows上拷贝文件也是这么。这到底是为什么?
剖析
先列一下设备情况。测试机器CPU是1037U,显存4Glinux系统对拷,通过HM76显卡支持USB3.0。源c盘是一块的WDMyBookEssential2TBUSB3.0联通硬碟,分区是NTFS,跳过文件系统直接次序读取速率曲线基本上从100MB/s+一路增加最后大约是50MB/s+。目的c盘是由两块STExpansion4TBUSB3.0联通硬碟组成的软RAID1阵列再使用lvm在其上创建ext4逻辑卷,实际写入速率在最快110MB/s左右,最慢大约60MB/s左右。
通过iostat查看rsync拷贝文件时的现象,发觉源c盘读取的时侯同时伴有写入操作,而且这块源c盘不仅拷贝数据进行读取不可能有其他进程在使用啊,那写入操作是那里来的呢?
经过一番查找,我发觉了一个之前从没注意过的事情,就是文件系统读取文件时,一般会伴随着写入。这是为何?缘由在于文件包含的一个属性最后访问时间。当文件被读取时,一般会更新这个文件的最后访问时间属性,因而会伴随着写入,因而机械c盘同时进行读写,破坏了原有连续的读操作,也可能伴随着重新寻道linux解压命令,因而慢了好多。
解决
方向确定解决方案就顺理成章,通过搜索,得悉通过给mount时添加noatime参数,即可不会更新最后访问时间,最大程度上防止读取时进行写入。
这儿有一点,就是默认mount时基本都使用relatime参数,即针对最后访问时间早于最后更改时间的文件,每晚只更新一次。这最大化增加了频繁读情况下的性能,而且对于冷数据首次读取并无帮助。
重新挂载后用rsync进行拷贝,提高到了50MB/s+,考虑到这是一个几乎全满而且有大量小文件的分区,这个性能早已很不错了。本次问题成功解决~
延展
事情到了这儿,我忽然想起了一个以前困惑我多年的问题。2011年我获得了梦寐以求的W520(外置一块5400转的500G硬碟),尽管性能强悍,而且开机时间基本上没有高于3分钟过。同盘拷贝文件最快速度基本都是20MB/s这个水平。并且长时间不用重新开机会更慢。到2016年的时侯,虽然我做竭力去优化和调整,开机时间早已到了6~8分钟这个级别。有幸当时赶上了SSD开始涨价,2016年中花了不到300元买了一块120G的mSATA固态硬碟,把系统分区联通过去后,开机时间降到了30秒以内。之后我把原先的硬碟放在硬盘位使用,此时从固态拷贝文件写入到机械c盘速率基本上能到80MB/s~100MB/s。假如当时我剖析并得出读取文件时,是既读又写造成读取性能严重减少,那我不至于忍受如此多年的龟速开机了。
Windows使用的NTFS,同样可以设置不在读取时更新最后访问时间数组,技巧是更改注册表的通配符,在Windows10下更改HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystem这个目录里的NtfsDisableLastAccessUpdate键,把值改为十六补码80000001,重启后即可防止读取文件时更新最后访问时间造成同时写入。总结一下这个操作带来的益处:
对于一些使用机械硬碟作为系统盘的机器来说,才能很大程度优化读取性能,推动开机速率与文件拷贝速率。
对于使用固态硬碟的机器,此操作仍具有意义。例如我的机器有手动备份功能red hat linux,定期如一周会手动备份一次。这个操作也能减少备份时读取冷数据导致的额外写入动作,有助于常年降低固态硬碟写入量,延长固态硬碟寿命
因而带来的益处,即个别应用可能依赖于最后访问时间这个属性做功能。我看见的说是个别电邮软件,还有安全软件。并且我并没有用到类似的电邮软件,在安全软件中我也把访问文件时引起扫描这这个特点关掉了(会严重减少软件读取的性能),所以我可以安全的取消这个特点。是否取不更新读取时间这个策略,最终还须要你按照实际情况来决定。
杂记
世上不存在绝对好的事情,所谓优化也必然伴随代价。每位人针对自己的情况,权衡优劣后linux系统对拷,作出最大化自己利润的选择。有得有失才是事物原本的样子。
参考