当前位置:网站首页>文件过多时ls命令为什么会卡住?
文件过多时ls命令为什么会卡住?
2020-11-06 21:04:00 【张彦飞allen】
不知道你有没有遇到过当一个文件夹下文件特别多,在下面执行ls
命令的时候要等好长时间才能展现出来的问题?如果有,你有想过这是为什么吗,我们该如何解决? 要想深入理解这个的问题产生的原因,我们就需要从文件夹占用的磁盘空间开始讨论了。
inode消耗验证
在《新建一个空文件占用多少磁盘空间?》中我提到了每一个文件会消耗其所在文件夹中的一点空间。文件夹呢,其实也一样会消耗inode的。 我们先看一下当前inode的占用情况
# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
......
/dev/sdb1 2147361984 12785020 2134576964 1% /search
再创建一个空文件夹
# mkdir temp
# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
......
/dev/sdb1 2147361984 12785021 2134576963 1% /search
通过IUsed可以看到,和空文件一样,空的文件夹也会消耗掉一个inode。不过这个很小,我的机器上才是256字节而已,应当不是造成ls
命令卡主的元凶。
block消耗验证
文件夹的名字存在哪儿了呢?嗯,和《新建一个空文件占用多少磁盘空间?》里的文件类似,会消耗一个ext4_dir_entry_2
(今天用ext4举例,它在linux源码的fs/ext4/ex4.h文件里定义),放到其父目录的block里了。根据这个,相信你也很快能想到,如果它自己节点下创建一堆文件的话,就会占用它自己的block。我们来动手验证一下:
# mkdir test
# cd test
# du -h
4.0K .
这里的4KB就表示消耗掉了一个block。 空文件不消耗block,空目录为啥一开始就消耗block了呢,那是因为其必须默认带两个目录项"."和".."。另外这个4K在你的机器上不一定是这么大,它其实是一个block size,在你格式化的时候决定的。
我们再新建两个空的文件,再查看一下:
# touch aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
# touch aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# du -h
4.0K .
貌似,没有什么变化。这是因为
- 第一、新的空文件不占用block,所以这里显示的仍然是目录占用的block。
- 第二、之前文件夹创建时候分配的4KB里面空闲空间还有,够放的下这两个文件项
那么我再多创建一些试试,动用脚本创建100个文件名长度为32Byte的空文件。
#!/bin/bash
for((i=1;i<=100;i++));
do
file="tempDir/"$(echo $i|awk '{printf("%032d",$0)}')
echo $file
touch $file
done
# du -h
12K .
哈哈,这时我们发现目录占用的磁盘空间变大了,成了3个Block了。当我们创建到10000个文件的时候,
# du -h
548K .
在每一个ext4_dir_entry_2
里都除了文件名以外,还记录着inode号等信息,详细定义如下:
struct ext4_dir_entry_2 {
__le32 inode; /* Inode number */
__le16 rec_len; /* Directory entry length */
__u8 name_len; /* Name length */
__u8 file_type;
char name[EXT4_NAME_LEN]; /* File name */
};
我们计算一下,平均每个文件占用的空间=548K/10000=54字节。也就是说,比我们的文件名32字节大一点点,基本对上了。 这里我们也领会到一个事实,文件名越长,在其父目录中消耗的空间也会越大。
本文结论
一个文件夹当然也是要消耗磁盘空间的。
- 首先要消耗掉一个inode,我的机器上它是256字节
- 需要消耗其父目录下的一个目录项
ext4_dir_entry_2
,保存自己inode号,目录名。 - 其下面如果创建文件夹或者文件的话,它就需要在自己的block里
ext4_dir_entry_2
数组
目录下的文件/子目录越多,目录就需要申请越多的block。另外ext4_dir_entry_2
大小不是固定的,文件名/子目录名越长,单个目录项消耗的空间也就越大。
对于开篇的问题,我想你现在应该明白为什么了,问题出在文件夹的block身上。 这就是当你的文件夹下面文件特别多,尤其是文件名也比较长的时候,它会消耗掉非常多的block。当你遍历文件夹的时候,如果Page Cache中没有命中你要访问的block,就会穿透到磁盘上进行实际的IO。在你的角度来看,就是你执行完ls
后,卡住了。
那么你肯定会问,我确实要保存许许多多的文件,我该怎么办? 其实也很简单,多创建一些文件夹就好了,一个目录下别存太多,就不会有这个问题了。工程实践中,一般的做法就是通过一级甚至是二级hash把文件散列到多个目录中,把单目录文件数量控制在十万或万以下。
ext的bug
貌似今天的实践应该结束了,现在让我们把刚刚创建的文件全部删掉,再看一下。
# rm -f *
# du -h
72K .
等等,什么情况?文件夹下的文件都已经删了,该文件夹为什么还占用72K的磁盘空间? 这个疑惑也伴随了我很长时间,后来才算是解惑。问题关键在于ext4_dir_entry_2
中的rec_len
。这个变量存储了当前整个ext4_dir_entry_2
对象的长度,这样操作系统在遍历文件夹的时候,就可以通过当前的指针,加上这个长度就可以找到文件夹中下一个文件的dir_entry
了。这样的优势是遍历起来非常方便,有点像是一个链表,一个一个穿起来的。 但是,如果要删除一个文件的话,就有点小麻烦了,当前文件结构体变量不能直接删,否则链表就断了。 Linux的做法是在删除文件的时候,在其目录中只是把inode设置为0就拉倒,并没有回收整个ext4_dir_entry_2
对象。其实和大家做工程的时候经常用到的假删除是一个道理。现在的xfs文件系统好像已经没有这个小问题了,但具体咋解决的,暂时没有深入研究,如果你有答案,欢迎留言!
开发内功修炼之硬盘篇专辑:
- 1.磁盘开篇:扒开机械硬盘坚硬的外衣!
- 2.磁盘分区也是隐含了技术技巧的
- 3.我们怎么解决机械硬盘既慢又容易坏的问题?
- 4.拆解固态硬盘结构
- 5.新建一个空文件占用多少磁盘空间?
- 6.只有1个字节的文件实际占用多少磁盘空间
- 7.文件过多时ls命令为什么会卡住?
- 8.理解格式化原理
- 9.read文件一个字节实际会发生多大的磁盘IO?
- 10.write文件一个字节后何时发起写磁盘IO?
- 11.机械硬盘随机IO慢的超乎你的想象
- 12.搭载固态硬盘的服务器究竟比搭机械硬盘快多少?
我的公众号是「开发内功修炼」,在这里我不是单纯介绍技术理论,也不只介绍实践经验。而是把理论与实践结合起来,用实践加深对理论的理解、用理论提高你的技术实践能力。欢迎你来关注我的公众号,也请分享给你的好友~~~
版权声明
本文为[张彦飞allen]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4746202/blog/4703274
边栏推荐
- 合约交易系统开发|智能合约交易平台搭建
- Filecoin的经济模型与未来价值是如何支撑FIL币价格破千的
- Did you blog today?
- 一篇文章教会你使用HTML5 SVG 标签
- With the advent of tensorflow 2.0, can pytoch still shake the status of big brother?
- Individual annual work summary and 2019 work plan (Internet)
- What is the difference between data scientists and machine learning engineers? - kdnuggets
- Mac installation hanlp, and win installation and use
- ES6 essence:
- A brief history of neural networks
猜你喜欢
From zero learning artificial intelligence, open the road of career planning!
Python基础变量类型——List浅析
Building and visualizing decision tree with Python
Interface pressure test: installation, use and instruction of siege pressure test
比特币一度突破14000美元,即将面临美国大选考验
一篇文章教会你使用Python网络爬虫下载酷狗音乐
Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】
Elasticsearch数据库 | Elasticsearch-7.5.0应用搭建实战
2019年的一个小目标,成为csdn的博客专家,纪念一下
Filecoin主网上线以来Filecoin矿机扇区密封到底是什么意思
随机推荐
Character string and memory operation function in C language
Building and visualizing decision tree with Python
前端都应懂的入门基础-github基础
Windows 10 tensorflow (2) regression analysis of principles, deep learning framework (gradient descent method to solve regression parameters)
Azure data factory (3) integrate azure Devops to realize CI / CD
Analysis of etcd core mechanism
ES6学习笔记(二):教你玩转类的继承和类的对象
Tool class under JUC package, its name is locksupport! Did you make it?
百万年薪,国内工作6年的前辈想和你分享这四点
Python crawler actual combat details: crawling home of pictures
TensorFlow中的Tensor是什么?
JVM memory area and garbage collection
MeterSphere开发者手册
Jetcache buried some of the operation, you can't accept it
带你学习ES5中新增的方法
If PPT is drawn like this, can the defense of work report be passed?
ES6学习笔记(五):轻松了解ES6的内置扩展对象
Using consult to realize service discovery: instance ID customization
Solve the problem of database insert data garbled in PL / SQL developer
Just now, I popularized two unique skills of login to Xuemei