linux --> 文件系统十问



二、 目录与文件

(1)为什么目录占用的空间是4096?
输入df –i查看inodes信息:

touch一个空的文件后再次df -i查看inodes信息:

这个实验证明操作系统“欺骗”了我们,它消耗掉了一个inode。那么inode的节点大小是多少呢,使用dumpe2fs命令可以帮助我们查看到这个东东的实际大小。

在输出的结果中我们可以找到下面这行:

它告诉我们每个inode的大小是256Byte。当然这个大小每台机器都会不一样,它实际上是在系统格式化磁盘的时候决定的。
好了,开篇第二个问题也有答案了。原来新建一个空的文件是会占用磁盘空间的,实际占用的是256Byte。哦,不,准确的说法应该是一个inode size,具体的值是在格式化时决定的。
再说说新建空目录吧,前面说了新建空目录会占用4KB的磁盘空间。那么仅仅如此吗? 我们同样在新建目录前后都使用df –i来监视系统inode的占用。

原来目录也是会占用一个inode节点的,第三个问题也有了答案了,新建一个空目录会占用磁盘空间4KB + inode size。 哦,这个在你的系统上也不一定是4K,它实际上一个block size。同样在dumpe2fs下可以看到。

只不过我的磁盘在格式化时采用的是4KB的大小,呵呵!
3、神秘的空目录的4KB
空目录占用的那4KB,这些空间是用来存什么的呢?cd到新建的目录下查看。

我们再新建两个空的文件,再查看下目录的空间占用情况。
因为空文件不占用block,所以这里显示的仍然是目录占用的block,和之前大小没有变化。使用php脚本创建100个文件名长度为32Byte的空文件。


这时我们发现目录占用的磁盘空间变大了,成了3个Block了。这就解答了我们开篇的第四个问题,文件名是存储在目录占用的block中的。另外新建了个空目录,创建了100个文件名长度为32*3个空文件,该临时目录占用的磁盘空间如下:

占用的block数目为什么没有变成3倍?其实Linux文件系统关于文件的结构体中除了文件名以外,还有其它的一些字段的,文件名变长3倍不会导致结构体变大3倍的,这点可以参考Linux系统内核相关书籍。
好了,到现在开篇问题6也有了答案了。文件名长了当然会对系统性能产生影响,因为这可能会导致更多的磁盘IO。很多程序员都喜欢将文件命名为有意义的长串,使人一看文件名就知道用途。当然我没说这样不好,但是如果你的文件数量相当大的时候,你就要考虑你的文件名是否导致你的目录block占用太多了。占用的空间倒是小事,磁盘很便宜,但是你得考虑下在目录下查找文件时操作系统的感受,操作系统可需要用你你提供的文件名进行字符串比较,而且运气不好的话需要将其名下所有block都搞一遍才行啊。(当然了,你的文件名长度不变态,而且数量没有达到十万数量级的话实际上这个开销也不会太大,但是这个开销你还是知道的为好)
至于开篇问题5,文件名最长多长。实际上Linux操作系统就是为了避免程序员不节制地使用长文件名,强加了个限制,不得超过255byte。
另外,大家有没有经验,在目录下文件很多的时候,我们使用ls命令时会很慢。现在大家知道原因了吧,这时实际上操作系统在读取当前目录的所有block,如果block比较多的话,可能得需要多次IO操作才能完成这个简单的ls命令。
我在自己的电脑某个目录下创建了一100W个空文件,ls命令1分钟还没出结果,被我ctrl+c掉了。在自己的项目中可不要这么干,虽然操作系统可以cache住你的目录数据,使你下次调用时会块很多,但我还是建议你单个目录下文件数目不要过万。否则你的程序在重启后首次运行时可能会出现性能不佳的情况。
好了,回到开篇问题7,你有答案了吗?一个目录下最多能建多少个文件,这个最多其实是受限于你目录所在分区的inode数量,你有100W个inode,你最多就可以新建100W个文件。但是,上面说了,单个目录下文件数量最好不要过万,否则会带来系统性能的问题。
4、文件的block
再做个关于文件的实验。我新建了个空目录,并在其下新建了个文件,里面只写了一个空格数据,保存后du命令显示如下:

这8K里有4K是目录的,也就可以算出操作系统为只包含一个空格的文件分配了4KB。其实文件的block比较简单的了,不像目录的block里会存很多文件系统的结构体,文件的block里只会保存文件的数据。上面这个实验表明,操作系统分配空间时是以block为最小单位。也就是说只要你的文件数据不为空,操作系统就至少会给你分配一个block来存储,直到你超过了4KB,操作系统再给你分配下一个block。所以对于开篇问题8,新建一个内容大小为1k的文件,实际会占用1个block(一般为4k)和一个inode(一般为256byte)。
其实文件系统在向磁盘发起IO请求的时候,也是以block size为单位的。哪怕你只向操作系统发起读取文件的2Byte,但是操作系统会一次性给你读取4KB回来。因此磁盘IO真的是很慢,而且我们只要访问了这2Byte,确实很有可能接下来继续访问这2byte后面的内容,这也就是程序局部性原理,所以操作系统索性一次性就多读取些回来了。呵呵,这就是开篇问题9的答案。
这就像我们去逛超市,逛一次真的是很浪费时间,这可要比坑爹的磁盘IO也慢许多了。我们总不会逛了一圈超市就买了一个苹果就回来了吧,我们肯定会多买些东西为家里以后的需求准备着,反正买一堆东西比买一个苹果也没多花多少时间,何乐为不为呢,就是这个道理。
再说说开篇问题10,怎么样设计你的文件能提高一些IO速度呢?那就是如果你知道你的要新建的文件大概会占用多大的空间的话,比如1M。那么你新建文件时就顺便和操作系统说一下,让它帮你将文件的size预留下来。这样实际上操作系统时会尽可能为你分配连续的block,这样你再读取这个文件时,磁头就省去很多寻道时间了,IO速度就显得快多了。
三、写在后面的话
前面我们说的都是基于我自己的文件系统,情形是一个block size是4KB,一个inode size是256byte,包括我虚拟机上的inode数量才只有140多万个。这些值实际上不是固定的,你完全可以在格式化你的硬盘的时候设置成其它的值。设置的原则就是看你的硬盘的容量,以及你的用途。
linux --> 文件系统十问的更多相关文章
- Linux文件系统十问---深入理解文件存储方式(rhel6.5,EXT4)【转】
本文转载自:https://blog.csdn.net/tongyijia/article/details/52832236 前几天在红黑联盟上看了一篇博客<Linux文件系统十问—深入理解文件 ...
- Linux文件系统十问,你知道吗?
关于文件系统,相信大家都不陌生.身为攻城狮的我们几乎天天都会与之打交道,但是细深剖一下,其中又有多少是我们理解深度不够的呢.那么让我们一起来看一下下面这一组Linux文件系统相关的问题吧: 1.机械磁 ...
- 十天学Linux内核之第五天---有关Linux文件系统实现的问题
原文:十天学Linux内核之第五天---有关Linux文件系统实现的问题 有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问 ...
- 十问 Linux 虚拟内存管理 (glibc) (二)
版权声明:本文由陈福荣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/184 来源:腾云阁 https://www.qclo ...
- Linux学习之二十-Linux文件系统
Linux文件系统 文件系统的定义 文件系统是操作系统的必备软件,文件系统是对一个存储设备上的数据(block)和元数据(inode)进行组织的一种机制.文件系统可以帮助用户管理磁盘空间,进行文件的快 ...
- 学习笔记:CentOS7学习之十四:linux文件系统
目录 1. 机械硬盘结构 1.1 机械硬盘结构 1.2 簇和block 2.文件系统结构 2.1 文件名 2.2 inode的内容 2.3 inode的大小 2.4 目录文件 2.5 block块大小 ...
- Linux 文件系统剖析
[转自]https://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/ 按照分层结构讨论 Linux 文件系统 在文件系统方面,Linu ...
- 24小时学通Linux内核之有关Linux文件系统实现的问题
有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问题,虽然Win10发布了,,但我还是好喜欢XP呀,好想回家用用家里的XP来 ...
- Linux文件系统的设计
总论: linux的文件系统设计非常优秀,总的来讲有两大部分,第一部分就是树形的组织结构,第二部分就是vfs,树形的组织结构组织了文件系统的表象,用户非常方便的使用,而vfs是文件系统的实现机理,它处 ...
随机推荐
- caffe︱cifar-10数据集quick模型的官方案例
准备拿几个caffe官方案例用来练习,就看到了caffe中的官方案例有cifar-10数据集.于是练习了一下,在CPU情况下构建quick模型.主要参考博客:liumaolincycle的博客 配置: ...
- 在CYGWIN下编译和运行软件Bundler ,以及PMVS,CMVS的编译与使用
本人按照 http://blog.csdn.net/zzzblog/article/details/17166869 http://oliver.zheng.blog.163.com/blog/sta ...
- Netty的并发编程实践1:正确使用锁
很多刚接触多线程编程的开发者,虽然意识到了并发访问可变变量需要加锁,但是对于锁的范围.加锁的时机和锁的协同缺乏认识,往往会导致出现一些问题.下面笔者就结合Netty的代码来讲解下这方面的知识. 打开F ...
- Windows DLL资料整理
1.使用Visual C++ 6.0创建dll 2. 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal) 要点: 1. 如果你的程序中没有涉及可变参数,最好使 ...
- RobotFramework下的http接口自动化Follow Response关键字的使用
Follow Response 关键字用于处理http中的重定向请求,常见的http 重定向请求包含http code为301和302 两种重定向请求,代表着某个URL地址发生了转移. http co ...
- 【BZOJ3680】吊打XXX(模拟退火)
[BZOJ3680]吊打XXX(模拟退火) 题面 BZOJ 题解 模拟退火... 就是模拟退火 然后这题有毒 各种调参数之后终于\(AC\)了.. 这种题就是玄学呀... 温度要调大 最后跑完还要向四 ...
- CodeIgniter怎么引入公共的头部或者尾部文件(实现随意引入或分区域创建header.html,bodyer.html,footer.html)
除非你天赋异禀,凡事基本对任何人来说都是开头难的,且开头的事情如果没有做好 往往会打掉一个人对于某件事的希望及其激情,所以咱们先从容易的事情开始慢慢建立自己 信心.后面的事情咱们再慢慢推进. 如果你是 ...
- Navicat for MySQL下载、安装与破解
一:下载Navicat for MySQL 进入 Navicat for MySQL下载 ,根据需要选择下载的版本,我选择的是Windows 64bit,任意选择一个镜像地址下载. 二:安装Navic ...
- MySQL服务读取参数文件my.cnf的规律研究探索
在MySQL中,它是按什么顺序或规律去读取my.cnf配置文件的呢?其实只要你花一点功夫,实验测试一下就能弄清楚,下面的实验环境为5.7.21 MySQL Community Server.其它版本如 ...
- java 向上转型与向下转型
转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展. 向上转型:子类引用的对象 ...