ext4文件系统delayed allocation相关研究

最近在一个项目上测试录音时,发现有丢数据的现象。通过串口发现打出了很多overrun的log。
overrun是驱动层给上层应用的一个通知,告诉上层数据取的太慢了,buffer被塞满了。
如果buffer塞满之后,上层仍不能及时取走数据,自然会导致数据丢失。

上层应用取数据过慢,能想到的有两个原因:
1、cpu繁忙,录音进程不能及时抢占到cpu。
2、录音进程写文件时速度过慢。

通过top命令,发现cpu并不繁忙,排除了第一种可能。

分析第二种可能。如果是写文件过慢,换一种介质是不是会有所不同。
最初是将录音文件写到nand flash上,有overrun错误和丢数据现象。
将录音文件保存到sd卡上,发现overrun错误没了,丢数据现象也没了。
基本上可以肯定是写文件过慢导致的了。

既然是文件写入过慢导致,那就比较比较nand flash与sd卡文件写入速度的差别。
使用命令:
sync; date; dd if=/dev/zero of=/data/xxx bs=4096 count=40960; sync; data
sync; date; dd if=/dev/zero of=/sdcard/xxx bs=4096 count=40960; sync; data
data是nand flash上一个分区。
测试发现,写入160M数据,nand flash耗时35s-45s不等,而sd卡耗时在20s左右。
会不会是其他进程也在访问nand flash导致?
打开blok_dump开关:echo 1 > /proc/sys/vm/block_dump,
通过命令while true; do dmesg -c; sleep 1; done发现有几个进程会经常访问nand flash。
将那几个进程干掉。
重新测试,发现nand flash速度依然如故。
有点费解,难道是什么地方设置或者其他进程影响?
为了尽可能减少其他进程影响,进入到recovery模式进行测试。
recovery模式下没有mount nand flash分区,手动mount:
mount -t ext4 /dev/block/mmcblk0px /data
然后进程测试。
sd卡的速度与正常模式下基本相同,nand flash速度大幅提升30%左右。
那就看看recovery模式下与正常模式下nand flash有什么差别。
recovery模式下,nand flash分区是通过命令:
mount -t ext4 /dev/block/mmcblk0p8 /data
挂载的。
正常模式下,是通过init.rc中的命令挂载的。
比较两处命令的差别,发现init.rc中的mount命令多了几个参数。
通过排除发现是参数nodelalloc的影响。
在recovery模式下,如果mount时加上nodelalloc,速度基本上与正常模式下相同。
正常模式下,去掉nodelalloc,速度也上去了。

delalloc是何方神圣?
原来是ext4引入的新技术。
以下是kernel中ext4文档中的介绍:
delalloc        (*)     Defer block allocation until just before ext4
                         writes out the block(s) in question.  This
                         allows ext4 to better allocation decisions
                         more efficiently.

nodelalloc              Disable delayed allocation.  Blocks are allocated
                         when the data is copied from userspace to the
                         page cache, either via the write(2) system call
                         or when an mmap'ed page which was previously
                         unallocated is written for the first time.
通过上面的介绍,基本上知道delalloc是什么。
但为什么会有delalloc的诞生,还需要继续研究。

通过ext4 wiki (参考[1]),找到关于ext4相关介绍(参考[2])。
其中对delay allocation的说明如下:
2.6. Delayed allocation
Delayed allocation is a performance feature (it doesn't change the disk format) found in a few modern filesystems such as XFS, ZFS, btrfs or Reiser 4, and it consists in delaying the allocation of blocks as much as possible, contrary to what traditionally filesystems (such as Ext3, reiser3, etc) do: allocate the blocks as soon as possible. For example, if a process write()s, the filesystem code will allocate immediately the blocks where the data will be placed - even if the data is not being written right now to the disk and it's going to be kept in the cache for some time. This approach has disadvantages. For example when a process is writing continually to a file that grows, successive write()s allocate blocks for the data, but they don't know if the file will keep growing. Delayed allocation, on the other hand, does not allocate the blocks immediately when the process write()s, rather, it delays the allocation of the blocks while the file is kept in cache, until it is really going to be written to the disk. This gives the block allocator the opportunity to optimize the allocation in situations where the old system couldn't. Delayed allocation plays very nicely with the two previous features mentioned, extents and multiblock allocation, because in many workloads when the file is written finally to the disk it will be allocated in extents whose block allocation is done with the mballoc allocator. The performance is much better, and the fragmentation is much improved in some workloads.

通过上述说明可知,将Delayed allocation与Extents、Multiblock allocation结合,可以大幅提升alloc的性能,并能改善碎片的问题。

接下来就该看看delayed allocation是怎样工作的。
同样在ext4 wiki (参考[1])中有个连接: Life of an ext4 write request(参考[3])。
其中对delayed allocation情况下的write请求进行了分析。
其中有一点要特别说明下,如果disk上的空间过少时,应该关闭delayed allocation功能。
因为delayed allocation的情况下,block是在真正写数据的时候才申请,而不是在上层应用调用write请求时。
如果在申请block时发现空间不足,导致写入失败,此时上层的write请求已经返回,所以没办法将错误通知给上层,最终导致上层应用认为写成功了,而实际没写入到介质中。
详细见下面说明:
In ext4_da_write_begin(), there's a potential fallback to nodelalloc mode. That happens if we are low on space (and possibly low on quota; but not sure). That's because when we estimate how much space is needed, we can guess wrong, especially as it comes to metadata allocation. We tend to guess high, because in particular for ENOSPC, we don't want to run out of space when we need to allocate an extent tree block. That's because in the delalloc write request, we don't actually do the block allocation until the writeback time --- and at that point we can't return an error to userspace. If we fail to allocate space at writeback time, data can potentially be lost without the calling application knowing about it. This is not the case for direct I/O, of course, since it doesn't use the writeback; but delalloc is all about what happens for buffered writes.) So when we come close to running out of disk space, we will turn off delayed allocation.

delayed allocation还有一个弊端,就是可能导致某一次的写入延迟特别长(参考[4])。
原因是,既然allocation都被delay了,肯定在writeback的时候要多花费时间。
writeback时会申请一把锁,上层应用write请求时也会申请这把锁。
如果上层应用write请求时刚好遇到writeback占用了锁,并进行了很长时间的操作,这个时候,上层应用的write请求只能等着了。

[1] https://ext4.wiki.kernel.org/index.php/Main_Page
[2] http://kernelnewbies.org/Ext4
[3] https://ext4.wiki.kernel.org/index.php/Life_of_an_ext4_write_request
[4] http://blog.tao.ma/?p=58

ext4 delalloc相关的更多相关文章

  1. 【转】ext4+delalloc造成单次写延迟增加的分析

    转自 http://blog.tao.ma/?p=58 这篇文章是淘宝内核组的刘峥同学在内部技术论坛上发表的一篇文章,但是由于刘峥同学目前没有blog,征得本人同意,贴在我的blog上,如果大家喜欢, ...

  2. Linux文件系统Ext2,Ext3,Ext4性能大比拼

    Linux kernel 自 2.6.28 开始正式支持新的文件系统 Ext4. Ext4 是 Ext3 的改进版,修改了 Ext3 中部分重要的数据结构,而不仅仅像 Ext3 对 Ext2 那样,只 ...

  3. linux里的进程简介

    /sbin/init         内核启动的第一个用户级进程,引导用户空间服务    [kthreadd]         内核线程管理[migration/0]      用于进程在不同的CPU ...

  4. 理解 Linux 的硬链接与软链接【转】

    转自:https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/index.html 从 inode 了解 Linux 文件 ...

  5. Linux上文件恢复工具

    文件恢复工具extundelete官网:http://extundelete.sourceforge.net/ 使用方法,在页面里找到download,下载源码安装包:extundelete-0.2. ...

  6. Linux内核进程

    公司数据库机器报警进程数高于1500,登进去ps命令看了一下,这么多进程并不认识,就在网上找了一些关于linux进程的资料,如下: idle 进程的pid=0,是由系统自动创建的第一个进程,也是唯一的 ...

  7. 理解 Linux 的硬链接与软链接(待研究)

    从 inode 了解 Linux 文件系统 硬链接与软链接是 Linux 文件系统中的一个重要概念,其涉及文件系统中的索引节点 (index node 又称 inode),而索引节点对象是 Linux ...

  8. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

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

    最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂 ...

随机推荐

  1. DE1-SOC的sof文件无法下载解决办法

    按照前面友晶科技的文档介绍一步步的做,后面发现根本无法下载sof文件. 通常思维: 一,器件选错了.器件选择错误会导致sof文件无法下载,至于这个ID具体怎么识别我没有追究.如果是这种错误Quartu ...

  2. MFC的消息映射机制揭秘

    MFC的设计者们在设计MFC时,紧紧把握一个目标,那就是尽可能使得MFC的代码要小,速度尽可能快.为了这个目标,他们使用了许多技巧,其中很多技巧体现在宏的运用上,实现MFC的消息映射的机制就是其中之一 ...

  3. 前端上传组件 - Plupload

    http://www.cnblogs.com/KTblog/p/4740852.html 效果: 起始界面. ------------- 可以上上传单个文件. ------------- 可以上传多个 ...

  4. [转]Linux(centOS6.5)下SVN的安装、配置及开机启动

    1.检查是否已安装 rpm -qa subversion 如果要卸载旧版本: yum remove subversion 2.安装 yum install subversion PS:yum inst ...

  5. Google出品的自动Web安全扫描程序 Skipfish 下载及安装使用方法

    Skipfish是由google出品的一款自动化的网络安全扫描工具,该工具可以安装在linux.freebsd.MacOS X系统和windows(cygwin). 谷歌工程师Michal Zalew ...

  6. C# 使用IENUMERABLE,YIELD

    C# 使用IENUMERABLE,YIELD 前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文 ...

  7. Mockito简介(转)

    Mockito 是目前 java 单测中使用比较流行的 mock 工具.其他还有 EasyMock,JMock,MockCreator,Mockrunner,MockMaker 及 PowerMock ...

  8. codeforces #267 C George and Job(DP)

    职务地址:http://codeforces.com/contest/467/problem/C 太弱了..这题当时都没做出来..思路是有的,可是自己出的几组数组总是过不去..今天又又一次写了一遍.才 ...

  9. VirtualBox安装及使用说明和虚拟机安装XP系统图文教程

    virtualbox是一款开源的虚拟机软件,它能够支持多种操作系统的安装如:Solaris.Windows.DOS.Linux.OS/2 Warp.BSD等系统作为client操作系统,而且最新版本号 ...

  10. HDU1058 Humble Numbers 【数论】

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...