放大缩小保证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 …

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

mysql储存过程把集合并_MySQL 多日志表结果集合拼接存储过程

通常MySQL单天的日志 只记录当天的日志信息,如果需要查看一月内的日志信息需要对每天的日志表结果集合进行拼接,通常用到 union通常MySQL单天的日志 只记录当天的日志信息,如果需要查看一月内的日志信息需要对每天的日志表结果集合进行拼接,通常用到 uni…

对于一个指针可以多次使用delete_【C++札记】new和delete

malloc,free和new,delete区别:a.malloc,free是C/C的标准库函数。new,delete是c的操作符。b.malloc申请的是内存,严格意义不是“对象”,new申请的可以理解为“对象”,new 时会调用构造函数,返回指向该对象的指针。c.对于…

java循环队列_Java 循环队列的实现

队列概念队列(Queue)是限定只能在一端插入、另一端删除的线性表。允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear),没有元素的队列称为“空队列”。队列具有先进先出(FIFO)的特性。普通顺序队列存在的问题在普通顺序队列中,入队的操作就是先将尾指针re…

java new 多线程_Java多线程实现(四种方法)

1.继承Thread类,重写run方法(其实Thread类本身也实现了Runnable接口)2.实现Runnable接口,重写run方法3.实现Callable接口,重写call方法(有返回值)4.使用线程池(有返回值)1.继承Thread类,重写run方法每次创建一个新的线程&#xff…

oracle删除唯一索引sql语句_高级SQL之在选择语句中使用更新和删除

点击蓝字关注我吧【本文详细介绍了数据库中在选择语句中使用更新和删除的方法,欢迎读者朋友们阅读、转发和收藏!】1 基本概念1.1 SQL UPDATE 语句Update 语句Update 语句用于修改表中的数据。语法:UPDATE 表名称 SET 列名称 新值 WHERE 列名…

java 多层异常_Java多层嵌套异常处理的基本流程

异常是程序中的一些错误,但并不是所有的错误都是异常,错误有时候是可以避免的。异常的对象有两个来源,一是Java运行时环境自动抛出系统生成的异常,而不管你是否愿意捕获和处理,它总要被抛出!比如除数为0的异…

java 获取子线程_Java 主线程获取子线程返回结果

1.自定义package com.jgyang.com;public class MySyncThreadTest {public static void main(String[] args) throws Exception {CustomRunnable cRunnacle new CustomRunnable();Thread thread new Thread(cRunnacle,"子线程");thread.start(); //子线程执行System…

串口工具securecrt_SecureCRT配置华为交换机部分命令

点上方蓝字“工控先生”免费快速关注本文由“135编辑由于工作需要,昨天临时需要从华为的光电交换机上面的console口查看一些端口的状态等,现整理如下,有需要的可以参考一下:硬件准备串口线,华为交换机连接将RJ45连接到…

java 跳转虚拟目录_java tomcat虚拟目录的深入了解

我们知道,Web网站中的内容(包括网页,图片,音频文件等)一般都存放在App的目录下。但随着网站内容的不断丰富,用户需要把不同层次的内容组织成网站的子目录。我们通常的做法是在网站主目录下新建子目录,并把相关的内容放…

redis工具类_SpringBoot 操作 Redis 数据

SpringBoot 操作 Redis 数据简介 Redis 是一个开源的NoSQL数据库,基于内存的键值存储,速度快。Redis 支持数据结构,如字符串,散列,列表,集和带范围查询的有序集。5种主要数据类型:字符串类型 …

span 里面的文字不显示_“无糖饮料”显示不含糖,为何还这么甜?原来里面加了这个...

长时间的高温天气让人离不开各种饮料,尤其是冰冻过之后味道更清爽的各种水。当你在外面晒着大太阳汗流浃背,突然听到扭开可乐雪碧瓶盖的那一声“ci~~~~”的时候,是不是瞬间有种眼前有个游泳池的感觉?且慢,更适合夏天的…