ext4文件系统的delalloc选项造成单次写延迟增加的分析

最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂载参数都使用了delalloc参数,怀疑是这个原因:ext4挂载的时候打开了delalloc选项,然后系统在没有分配磁盘块的情况下写写写,到page cache被回写到磁盘时,发现磁盘已经满了,没办法分配新的磁盘块了,就Hang住了。

 

这篇文章是淘宝内核组的刘峥同学在内部技术论坛上发表的一篇文章,但是由于刘峥同学目前没有blog,征得本人同意,贴在我的blog上,如果大家喜欢,请去新浪微博关注他。:)

日前线上在升级到Ext4文件系统后出现应用写操作延迟开销增大的问题。造成这一问题的根源目前已经查明,是由于Ext4文件系统的一个新特性——Delay Allocation造成的。(后面简称delalloc)

在详细分析这一问题之前,先来介绍一下Ext4文件系统的delalloc特性。这一特性简要概括起来就是将以前在buffer IO中每次写操作都会涉及的磁盘块分配过程推迟到数据回写时再进行。我们知道,在进行Buffer Write时,系统的实际操作仅仅是为这些数据在操作系统内分配内存页(page cache)并保存这些数据,等待用户调用fsync等操作强制刷新或者等待系统触发定时回写过程。在数据拷贝到page cache这一过程中,系统会为这些数据在磁盘上分配对应的磁盘块。

而在使用delalloc后,上面的流程会略有不同,在每次Buffer Write时,数据会被保存到page cache中,但是系统并不会为这些数据分配相应的磁盘块,仅仅会查询是否有已经为这些数据分配过磁盘块,以便决定后面是否需要为这些数据分配磁盘块。在用户调用fsync或者系统触发回写过程时,系统会尝试为标记需要分配磁盘块的这些数据分配磁盘块。这样,文件系统可以为这些属于同一个文件的数据分配尽量连续的磁盘空间,从而优化后续文件的访问性能(因为传统机械硬盘顺序读写的性能要比随机读写好很多)。

了解完delalloc特性的工作过程后,我们开始分析线上遇到的问题。线上应用的I/O模式可以简化为一个单线程追加写操作的程序,每秒写入2、3M数据,写操作后等待系统自动将数据回写到磁盘。在使用delalloc后,每次Buffer Write操作,系统都会去查询数据是否分配了磁盘块,这一过程需要获得一把读锁 (i_data_sem)。由于这时还没有触发回写操作,因此可以顺利获取i_data_sem,系统完成数据拷贝工作,并返回。由于仅仅是内存拷贝的过程,所以这一操作速度相当快。当系统开始进行回写操作时,系统会成批为数据分配磁盘块,这一过程同样需要获取i_data_sem,并且需要加写锁​以保证数据的一致性。由于使用delalloc后,需要分配的磁盘块比nodelalloc情况下多很多(nodelalloc情况下每5秒文件系统会提交日志触发回写;delalloc情况下,系统会在约每30秒左右触发一次回写),因此这一延迟时间较长。如果这时应用程序进行一次Buffer Write,则该操作在尝试获得i_data_sem时会等待上述磁盘块分配完成。由此造成写操作等待很长时间,从而影响应用程序的响应延迟。

在上面的分析中已经提到,delalloc是将多次磁盘块分配的过程合并到一次中来进行,那么是否真如预想的那样,delalloc的平均延迟会小于nodelalloc的情况呢?我们使用fio来做如下测试:设置bs=4k,单线程每秒追加写入5M,程序运行3分钟,我们来看一下最后fio对延迟的统计结果:

delalloc:
lat (usec): min=2 , max=193466 , avg= 5.86, stdev=227.91

nodelalloc:
lat (usec): min=3 , max=16388 , avg= 7.00, stdev=28.92

从上面的统计结果看,写操作的平均延迟:打开delalloc后为5.86us,关闭delalloc后为7.00us;最小延迟delalloc为2us,nodelalloc为3us;但是最大延迟delalloc为193.466ms,nodelalloc下仅为16.388ms。可见delalloc确实将多个写操作请求集中到了一起来进行。因此在提供较低平均延迟的情况下,会造成某次写操作的延迟较大。

通过上面的分析可以看到,目前会受到Ext4的delalloc特性影响的应用必须具备如下条件:
0. Buffer IO
1. 写操作过程中会涉及磁盘块的分配,主要是记录日志这类追加写操作;
2. 每次写操作后没有刷新数据,而是等待系统自动进行回写;
3. 对延迟有较高要求。

解决方法:关闭delalloc
1. mount -t ext4 -o remount,nodelalloc /${dev} /${mnt};
2. 编辑/etc/fstab中相关mount项,添加nodelalloc挂载参数

转载于:https://www.cnblogs.com/cobbliu/p/5603472.html

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

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

相关文章

前端学习(1982)vue之电商管理系统电商系统之删除参数的操作

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

前端学习(1983)vue之电商管理系统电商系统之清空表格数据

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

python 进程和线程

python中的进程、线程(threading、multiprocessing、Queue、subprocess) Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然。你做到了你就比别人NB。 我们先了解一下什么是进程和线程。 进程与线程的历史 我们都知…

NYU Hand Pose Dataset

http://cims.nyu.edu/~tompson/NYU_Hand_Pose_Dataset.htm#overview 转载于:https://www.cnblogs.com/guochen/p/5610681.html

前端学习(1984)vue之电商管理系统电商系统之完成静态属性

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

java实现文件在线预览

RequestMapping("/preview1") public void er(HttpServletResponse response){File file new File("G:\\桌面\\Thymeleaf3.0中文翻译文档www.java1234.com.pdf");if (file.exists()){byte[] data null;try {FileInputStream input new FileInputStream(…

Python 运维(三):使用 zipapp 将 Python 程序打包成单个可执行文件

大家好,我是水滴~~ 在 Python 开发中,我们经常需要将应用程序打包成可执行文件,以便在不具备 Python 环境的计算机上运行。Python 提供了多种打包工具,其中之一就是 zipapp。zipapp 可以将 Python 应用程序及其依赖打包成一个单独…

FreeMarker 集合遍历

freemarker list (长度,遍历,下标,嵌套,排序) 1. freemarker获取list的size &#xff1a; Java ArrayList<String> list new ArrayList<String>(); Freemaker ${list?size} 2. list的遍历&#xff1a; <#list animals as being> <tr> <td>${be…

java 返回文件的二进制字符串给前端

RequestMapping(value "/fileToStream", method RequestMethod.GET)ApiOperation("将文件转成流传给前端")public WebResponse fileToStream(HttpServletResponse response, HttpServletRequest request){ // // 自动判断下载文件类型 // response.set…

【BZOJ-3033】太鼓达人 欧拉图 + 暴搜

3033: 太鼓达人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 204 Solved: 154[Submit][Status][Discuss]Description 七夕祭上&#xff0c;Vani牵着cl的手&#xff0c;在明亮的灯光和欢乐的气氛中愉快地穿行。这时&#xff0c;在前面忽然出现了一台太鼓达人机台&#xff…

ubuntu创建、删除文件及文件夹,强制清空回收站方法

mkdir 目录名 > 创建一个目录 rmdir 空目录名 > 删除一个空目录 rm 文件名 文件名 > 删除一个文件或多个文件 rm –rf 非空目录名 > 删除一个非空目录下的一切 touch 文件名 > 创建一个空文件 重命名文件&#xff08;夹&#xff09; / 移…

前端学习(1987)vue之电商管理系统电商系统之通过路由加载商品列表

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

unity, 同步物体坐标一定要在LateUpdate中进行

设a为主动物体&#xff0c;b为跟随物体。 如果a,b都在同一个Update里更新坐标&#xff0c;那么两者自然是同步的。 如果a在a.Update里更新位置&#xff0c;而b在b.Update里将自己的位置更新为与a相同&#xff0c;那就会有误差。 而且即使a的运动非常缓慢平滑&#xff0c;b也会出…

前端学习(1988)vue之电商管理系统电商系统之获取商品列表

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

为什么objc_msgSend必须用汇编实现

译者前言 总是看到有人说用汇编实现objc_msgSend是为了速度快&#xff0c;当然这个不可否认。但是难道没有别的原因&#xff1f;于是就看到了这篇文章&#xff0c;遂翻译之&#xff01;。 我自己的理解就是&#xff0c;用汇编实现&#xff0c;是为了应对不同的“Calling conven…

前端学习(1989)vue之电商管理系统电商系统之渲染商品列表数据

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

前端学习(1990)vue之电商管理系统电商系统之自定义时间过滤器

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

【开源】.net 分布式架构之监控平台

开源地址: http://git.oschina.net/chejiangyi/Dyd.BaseService.Monitor .net 简单监控平台&#xff0c;用于集群的性能监控,应用耗时监控管理&#xff0c;统一日志管理等多维度的性能监控分析。集群的性能监控:&#xff08;需要服务器部署监控节点&#xff09; 1. 目前仅支持w…