放大缩小保证div对齐_NFS Write IO 不对齐深度分析

导读:NFSClient 对大多数的应用写入没有做对齐优化,本文根据 IO 不对齐的原因给出了若干实践建议。

作者 | 裴晓辉

背景

最近团队小伙伴弗曼统计了线上用户数据写入对齐情况,通过统计数据发现了一个有趣的现象: 用户写入请求中近 70% 的数据块 4K 不对齐,这也就是说 NFSClient 对大多数的应用写入没有做对齐优化。

下面会从 NFSClient BufferWrite 实现流程的维度解释 IO 不对齐的原因,最后据此给出了若干实践建议。

场景分析

应用程序一般可以使用 DirectIO 或 BufferIO 两种方式向文件写入数据。在 DirectIO 模式时 NFSClient 直接将用户 IO 通过 RPC 发送给服务端,因此 DirectIO 方式写入 NFSClient 不会做对齐,但考虑到应用程序使用 DirectIO 时一般会在应用侧做对齐,因此非对齐 IO 的多数应该是 BufferIO 方式。

内核使用 struct nfs_req 对象记录某个缓存页更改情况,同时使用 struct page 对象的 private 字段保存,因此只需分析 BufferIO 时 nfs_req 的处理逻辑就能够知道对齐规则。NFSClient 调用 nfs_updatepage() 更新 nfs_req 对象,其核心代码如下:

7ded707d0c20a7ca33a8551cce9e24c6.png

从上图红色框中代码可以看出来,NFSClient 会尝试按照缓存页大小对 offset/count 对齐,继续查看 nfs_can_extent_write() 函数实现:

98c023059ec290003834953271be7e15.png

从上述代码可知:

1) 若为同步写,则不尝试对齐,这是因为对同步写做对齐并没有明显收益还会放大 IO;

2) 若缓存页内容不是最新,则不允许对齐,否则就要读惩罚,注意 nfs_write_begin() 函数已处理是否需要读惩罚;

3) 若持有 Write Delegation,则允许对齐,因为 Write Delegation 保证本地缓存数据一定是最新,关于 Delegation 可参考文章《NFSClient Delegation 实现与陷阱》;

4) 若不持有文件锁,则允许对齐,注意此处依据 NFSClient 设计哲学的一个假设:应用在不持有文件锁写入数据时,应用侧应该保证文件不会被多客户端修改;

5) 若持有全文件的写锁,则允许对齐,因为写锁保证了本地缓存数据肯定是有效的且不存在多客户端更改,此外这里要求全文件锁的原因是为了简化代码逻辑。

合并规则

上面提到内核使用 struct nfs_req 对象表示每个缓存页的更改情况,考虑到 struct nfs_req 只能表示单区间,因此 BufferIO 需合并同一个缓存页的多次更改,合并规则较为简单:

两个写合并后必须是一个连续的区间。

相关代码实现可参考 nfs_try_to_update_request() 函数,代码较为简单,故不再详细描述。从合并规则还可以知道:同一个缓存页上的两个非连续 IO 需要两次 RPC 写入。

缓存页 UpdateToDate 设置

从场景分析中知道缓存页是否设置了 UpdateToDate 标记是同一缓存页上的两个 IO 能否合并的重要前提条件,那 NFSClient 是什么时候将缓存页设置为 UpdateToDate 状态的呢?总的来说,NFSClient 在两个地方尝试设置该标记:

1) 将缓存页加入到 address space 时,实现代码是 nfs_write_begin() 函数,相关逻辑如下:

6f258354155d1309bf5d9c8b82e4d900.png

继续查看 nfs_want_read_modify_write() 函数实现:

5e9f673cc31537692073b2e06d1b2d91.png

上图中蓝色框中是 pNFS 相关处理暂时不做讨论,红色框则是一般情况下将缓存页加入到 address space 时是否需要读惩罚(读取数据后缓存页内容自然为最新),具体的需满足如下几个条件:

a) 若应用打开文件模式允许读,则允许读惩罚,这是因为根据数据的局部性原理,刚写入的数据很可能再次读;

b) 缓存页内容不是最新,若已经是最新很显然没必要再次读老数据;

c) 当前缓存页没有正在进行的 IO,也就是说没有向服务端有读写请求,注意 nfs_req 只能表示单个 IO,显然此时不允许读;

d) 本次修改只是缓存页的局部内容,显然如果全覆盖是没有必要读入老数据;

2) 当内核将待修改的数据拷贝到缓存页后会调用 nfs_write_end() 函数通知 NFSClient 数据已经拷贝到缓存页,此时 NFSClient 需根据写入情况设置缓存页是否为最新的状态:

5553e5fc36dcd0aadb24e7f45b9ce5dd.png

通过上面代码可知:

a) 蓝色框中表示缓存页是文件变大时新追加的缓存页,此时缓存页内容为全零,自然可设置为最新;

b) 红色框中表示缓存页中所有的有效数据均被覆盖,此时缓存页内容必然为最新;

总之,数据写入后若完全覆盖该缓存页的所有原有效数据,则设置为最新。

实践建议

至此基本搞清楚了 NFSClient BufferWrite 的对齐实现逻辑,感兴趣的同学可自行编写测试用例验证。结合对齐实现和测试验证,初步的可给出如下建议:

1) O_SYNC 方式不会做缓存页对齐;

2) 当文件被大量小块 IO 重复覆盖写时,可考虑用 O_RDWR 方式打开(注意副作用是会有读惩罚),有利于聚合同一个缓存页的写 IO,减少 RPC 次数;

3) 使用 O_WRONLY 方式打开时,同一缓存页的不连续更改不会做聚合,每个 IO 都会触发一次 RPC,降低访问性能;

4) 使用类 MPI 方式多客户端并发修改同一文件时,条带大小应该做到缓存页对齐,否则可能会导致数据被错误覆盖;

5) 不恰当的使用文件锁会导致不做缓存页对齐;

6) 不使用文件锁时小块 IO 可能会缓存页对齐,导致 IO 放大。

总结

缓存页对齐是提高 BufferIO 访问性能地有效手段,NFSClient 在设计上尽量会尝试缓存页对齐,但受限于 NFS 共享特性的约束,也只能对较为有限的情况做缓存页对齐,这就潜在地要求应用侧配合才可以达到最优性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL+for+Mac下载_MySQL For mac

MySQL For Mac官方版是一款可以在苹果电脑MAC OS平台上使用的多线程的、结构化查询语言(SQL)数据库服务器,SQL在世界上是最流行的数据库语言,MySQL For Mac最新版的执行性能非常高,运行速度非常快,并且MySQL For Mac非常容易使用。MySQL For …

mysql断电不受影响db引擎_一次服务器断电,造成innodb引擎表(日志表)损坏的解决办法...

1、mysql日志报错innodb引擎提示数据库没有正常关闭,报innodb错误180112 0:49:28 InnoDB: Database was not shut down normally!InnoDB: Starting crash recovery.InnoDB: Reading tablespace information from the .ibd files...InnoDB: Restoring possible hal…

mysql简单语句_MySQL 简单的语句

一:连接MySQL格式: mysql -h主机地址 -u用户名-p用户密码1. mysql –uroot–p123456 连接本机MYSQL2. mysql –h108.108.108.108 –uroot –p123456 连接远程MYSQL退出MYSQL环境,exit (回车) 或者 CtrlC二:修改密码 格…

石头剪刀布程序流程图_石头剪刀布!我要与电脑决战到天明!(14天)

1、学习心得原来一直以为,学了这个600集视频,应该就能自己做点啥了,比如我的最终目的:爬学区房。但是我今天学的时候,隐隐觉得,好像不大现实。毕竟,这都到了200多集,我依然还是个纯粹…

python做地图导航_「Python」利用高德地图做你想做之事

玩grasshopper基本上都知道OpenStreetMap 这个地图网站,毕竟有一个好用的地图插件,可以在Rhino中绘制出所需,但是一个不好的地方就在于国内的数据量太少,无法满足我们的需求。此次所讲的高德地图基本上可以解决我们的痛点&#xf…

python列表存储字符串_Python 基础知识全篇-字符串列表

现在我们已经对列表有了一定的了解。回头看一下字符串,会发现它不过是字符的集合,即包含一系列字符的列表。它们背后的工作原理是如此的相似,接下来让我们一探究竟吧。作为字符列表的字符串就像列表一样,我们可以对一个字符串作循…

elementui分页组件按钮样式修改_Vue使用Elementui修改默认最快方法!

相信大家都需要过,在Vue中使用Elementui的时候,遇到最多也最蛋疼的问题就是修改默认样式,接下来直奔主题;// template :text-inside"true" :stroke- :percentage"70" >-progress>默认样式方法…

MySQL创建不了计划任务_MySQL创建定时任务(或计划任务)

MySQL 从 5.1.6 版本起,增加了一个时间调度器(Event Scheduler),可以做定时操作,精确到秒来执行。首先查看定时任务是否开启,命令SHOW VARIABLES LIKE event_scheduler;若没有开启,则使用如下命令开启定时器SET GLOBAL…

ipython怎么安装_ipython的两种安装方式

第一种方式:通过python-pip安装ipythonrpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpmyum install python-pippip install ipython1.2.1//适用Python2.6pip list//可以显示已安装的模块卸载pip uninstall ipython1.2.1第二种…

python 全局变量使用报错没有定义_Python变量作用域代码解析

本篇文章小编给大家分享一下Python变量作用域代码解析,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。特点python的作用域是静态的,在源代码中变量名被赋值的位置决定…

python 画出决策边界_Python3入门机器学习 - 逻辑回归与决策边界

logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。因此因变量就为是否胃癌,值为“…

mysql基础测试_MySQL基础知识测试

SQL基础知识测试1 . SQL 指的是?Strong Question LanguageStructured Question LanguageStructured Query Language2 . 哪个SQL 语句用于从数据库中提取数据?EXTRACTSELECTOPENGET3 . 哪条SQL 语句用于更新数据库中的数据?MODIFYSAVE ASUPDAT…

mybatis字符串转成数字_计算机储存数字和字符的方法你了解多少?

前语:不要为了读文章而读文章,一定要带着问题来读文章,勤思考。本文链接: http://1t.click/J7E前言最近在学习中涉及到计算机储存、传输数字和字符等操作,由于对字节、2进制、10进制、16进制、ASCII码的概念以及它们之…

usb连接不上 艾德克斯电源_艾德克斯HT3150联机和IT6720校准联机记

大概2年前,坛里入了一台设置电压比输出电压高几伏的IT6720电源,到手发现,里面被修得惨不忍睹。到手的时候是110V的,没想到这种型号,跳线要改焊控制变压器和高压部分两个跳线,只修改了控制变压器跳线&#x…

经典兔子问题python视频_Python练习题 007:兔子生兔子

【Python练习题 007】 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?------------------------------------------------------…

android调用python框架_在Java中从Android应用程序执行Python脚本?

我正试图找到一种在Android中从Java代码执行Python脚本的方法。我对这个问题做了一个研究,但我发现的唯一问题是,如何在APK for android(Kivy e.t.c.)中转换python脚本。更具体地说,我有一个包含很多函数的脚本,我想做的是在我的j…

使用java向ftp上传多张图片_ftp免费空间,利用ftp工具定时连接ftp免费空间教程及java配置...

IIS7服务器管理工具这款ftp客户端软件,可以批量管理ftp站点,还可以实现ftp定时上传、定时下载,定时备份、自动更新等功能。关于ftp客户端功能,它主要实现以下四点功能:1、ftp 批量操作2、ftp 定时同步(上传…

mysql fulltext 分页_关于MySQL的FULLTEXT实现全文检索的注意事项

对于英文,MySQL的FULLTEXT属性来实现全文检索是相当方便且高效的,但是在使用过程中需要注意一些事项。首先对我们对需要进行检索的字段添加FULLTEXT属性(假设已经建表):SQL:alter table table_name add fulltext index(filed_1,fi…

损失函数的意义和作用_损失函数的可视化:浅论模型的参数空间与正则

点击蓝字关注我们作者丨土豆知乎来源丨https://zhuanlan.zhihu.com/p/158857128本文已获授权,不得二次转载前言在深度学习中,我们总是不可避免会碰到各种各样的损失函数。通常来说,损失函数都是高维的函数,难以可视化为人类可以分…

postgres 把一个表的值转成另一个表的字段名_用LUT来做一个可动态配置的卷积核...

引言由于卷积核数据在计算过程中保持不变,更新较慢。这样就可以利用LUT来存储权重并同时进行乘法运算。LUT乘法器的实现很早就已经研究过,本论文正是在此基础上,提出了用于实现可配置的卷积实现方法。基于LUT的乘法器不会受到FPGA中DSP资源的…