做网站要做哪些,自己想做个网站怎么做的,东莞建设公司网站,建筑设计适合的电脑我在知乎和公众号上都提到过#xff0c;我 2012 在腾讯工作的时候写过一篇《Linux文件系统十问》。总有人问我这篇文章在哪里能看到#xff0c;如今外网唯一的正版链接-腾讯学堂也挂了#xff0c;网上能搜到的全是盗版。所以今天我干脆就正式给大家发一遍。以下是这篇文章的… 我在知乎和公众号上都提到过我 2012 在腾讯工作的时候写过一篇《Linux文件系统十问》。总有人问我这篇文章在哪里能看到如今外网唯一的正版链接-腾讯学堂也挂了网上能搜到的全是盗版。所以今天我干脆就正式给大家发一遍。以下是这篇文章的正文。关于文件系统相信大家都不陌生。身为攻城狮的我们几乎天天都会与之打交道但是细深剖一下其中又有多少是我们理解深度不够的呢。那么让我们一起来看一下下面这一组 Linux 文件系统相关的问题吧1、机械磁盘随机读写时速度非常慢操作系统是采用什么技巧来提高随机读写的性能的2、touch 一个新的空文件占用磁盘空间吗占用的话占用多少3、新建一个空目录占用磁盘空间吗占用多少和新建一个文件相比哪个占用的更大4、你知道文件名是记录在磁盘的什么地方吗5、文件名最长多长受什么制约6、文件名太长了会影响系统性能吗为什么会产生影响7、一个目录下最多能建立多少个文件8、新建一个内容大小 1 k 的文件实际会占用多大的磁盘空间9、向操作系统发起读取文件 2 Byte 的命令操作系统实际会读取多少呢10、我们使用文件时要怎么样来能提高磁盘IO速度如果你能想也不用想的就回答上来百分八十的问题那么请关掉本篇文章吧。如果不能而且你也像作者一样对有窥探操作系统隐私的嗜好那么就请随我一起来探索文件系统的这些有趣的地方相信理解了这些之后对我们手中的工作会有很大的帮助。这篇文章实验所用文件系统是 ext 系的。一、磁盘构成及分区1、磁盘物理结构还是先从最基本的磁盘物理结构说起吧注意本文只讨论机械磁盘SSD 不在本文讨论范围之内。我们人类管理任何事物总是习惯先划分出一定的结构在此规则的基础上进行管理。军队分军、师、旅、团和营。公司分事业群、部门、中心和小组。然后对于管理磁盘分磁盘面、磁头、磁道、柱面和扇区。磁盘面磁盘是由一叠磁盘面组成见图。磁头(Heads)每个磁头对应一个磁盘面负责该磁盘面上的数据的读写。。磁道(Track)每个盘面会围绕圆心划分出多个同心圆圈每个圆圈叫做一个磁道。柱面(Cylinders)所有盘片上的同一位置的磁道组成的立体叫做一个柱面。扇区(Sector)以磁道为单位管理磁盘仍然太大所以计算机前辈们又把每个磁道划分出了多个扇区见下右图本人爱上 Linux 的一个原因就是只要你愿意下功夫你就能把 Linux 的内部逻辑彻底铺开来看这点比 Windows 要好太多了。Linux 上可以通过 fdisk 命令来查看当前系统使用的磁盘的这些物理信息。以上是我本人的一台虚拟机的磁盘物理信息。可以看出我的磁盘有 255 个 heads也就是说共有 255 个盘面。3263 个 cylinders也就是说每个盘面上都有 3263 个磁道 63 sectors/track 说的是每个磁道上共有 63 个扇区。命令结果也给出了 Sector size 的值是 512 bytes。那我们动笔算一下该磁盘的大小吧。255 盘面 * 3263 柱面 * 63 扇区 * 每个扇区 512 bytes 26839088640 byte。结果是 26.8 G,和磁盘的总大小基本相符至于fdisk给出的详细结果相差了约4M的大小笔者也没有弄彻底明白有兴趣的读者可以继续研究。不过要注意一点就是上面的盘面等数据是逻辑上的是物理盘面映射转化而来的这个转化关系我现在还没搜到特别好的资料。2、分区分区是操作系统对磁盘进行管理的第一步这也是我们任何一个计算机使用者都非常熟悉的概念。例如Windows下的C、D、E、F盘。那么请思考一下思考前面的磁盘的详细物理结构已经有了如果让你把整块磁盘分成C、D等分区你会怎么分呢方案一255 个盘面C 盘是 0-100 盘面 D 盘是 101-200 个盘面, ……方案二3263 个柱面C 盘 0-1000 个柱面D 盘 1001-20001 个柱面, ……对于以上的两个方案你会选择哪一种呢先说下磁盘 IO 时的过程。第一步首先是磁头径向移动来寻找数据所在的磁道。这部分时间叫寻道时间。第二步找到目标磁道后通过盘面旋转将目标扇区移动到磁头的正下方。第三步向目标扇区读取或者写入数据。到此为止一次磁盘 IO 完成。故单次磁盘 IO 时间 寻道时间 旋转延迟 存取时间。对于旋转延时现在主流服务器上经常使用的是1W转/分钟的磁盘每旋转一周所需的时间为60*1000/100006ms故其旋转延迟为0-6ms。对于存取时间一般耗时较短为零点几 ms。对于寻道时间现代磁盘大概在 3-15 ms其中寻道时间大小主要受磁头当前所在位置和目标磁道所在位置相对距离的影响。其实采用哪一种最主要看的是那种方式性能更快。因为同一分区下的数据经常会一起读取假如采用第一种那么这样磁头就需要在 3000 多个 track 间不停地跳来跳去这样磁盘的寻道时间就会翻倍磁盘性能就会下降。而对于方案二假如对于磁盘C只需要在磁头在 1-1000 个磁道间移动就可以了大大降低了寻道时间。实际上分区并不是从 0 开始的磁盘的第一个磁道对应的柱面会被用来安装引导加载程序以及磁盘分区表。所以方案二的分区方式可以降低磁盘 IO 时间中的寻道时间部分所以所有的操作系统采用的都是方案二没有用方案一的。在Linux下使用过fdisk进行分区的话可以注意到以下信息。这充分证明了操作系统是采用方案二的。回到开篇问题 1操作系统是采用什么技巧来降低随机读写的性能问题的呢操作系统通过按磁道对应的柱面划分分区来降低磁盘 IO 所花费的的寻道时间 进而提高磁盘的读写性能。二、目录与文件1、引子好了磁盘基础都说完了那我们正式进入主题开始我们 Linux 文件系统相关的讨论吧。文件系统不就是目录和文件吗这二位可是我们熟悉的不能再熟悉的家伙了。可你确认它不是你的那位熟悉的陌生人么我先来来创建个空目录和空文件吧查看结果如下图我们都知道第五列显示的是占用的空间大小那么我来提个几个小小的问题吧。1为什么目录占用的空间是 40962为什么空文件占用的空间却是 03如果空文件真占用 0 byte 空间那么该文件的文件名、创建者以及权限-rw-rw-r—等文件夹相关的信息都存到哪儿去了2、我就不信空文件不占用空间为了解开这个谜底需要借助 df 命令。输入 df –iLinux 结果中红框位置处显示的是 inodes 的相关信息如果你对 inode 的概念不熟悉你可以暂时把它当成一个操作系统秘密管理的一个家伙会占用空间就行了。接下来我 touch 一个空的文件后再次 df -i。虽然前面操作系统告诉我们一个新建的空文件占用的空间是 0。但是这个实验却证明操作系统“欺骗”了我们它消耗掉了一个 inode。那么 inode 的节点大小是多少呢使用 dumpe2fs 命令可以帮助我们查看到这个东东的实际大小。在输出的结果中我们可以找到下面这行。它告诉我们每个 inode 的大小是 256 Byte。当然这个大小每台机器都会不一样它实际上是在系统格式化磁盘的时候决定的。好了开篇第二个问题也有答案了。原来新建一个空的文件是会占用磁盘空间的实际占用的是 256 Byte。哦不准确的说法应该是一个 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 中的。接下来我又还证明了每个目录 block 中能保存的文件名个数是和文件名的长度有关的好像有点废话的意思不过亲手证明自己的猜想还是有点小爽的。我又另外新建了个空目录创建了 100 个文件名长度为 32*3 个空文件该临时目录占用的磁盘空间如下你可能会问我为什么文件名变成了 3 倍后占用的 block 数目为什么没有变成 3 倍。其实Linux文件系统关于文件的结构体中除了文件名以外还有其它的一些字段的文件名变长3倍不会导致结构体变大 3 倍的这点可以参考 Linux 系统内核相关书籍。好了到现在开篇问题 6 也有了答案了。文件名长了当然会对系统性能产生影响因为这可能会导致更多的磁盘 IO。很多程序员都喜欢将文件命名为有意义的长串使人一看文件名就知道用途。当然我没说这样不好但是如果你的文件数量相当大的时候你就要考虑你的文件名是否导致你的目录 block 占用太多了。占用的空间倒是小事磁盘很便宜但是你得考虑下在目录下查找文件时操作系统的感受操作系统可需要用你你提供的文件名进行字符串比较而且运气不好的话需要将其名下所有 block 都搞一遍才行啊。当然了你的文件名长度不变态而且数量没有达到十万数量级的话实际上这个开销也不会太大但是这个开销你还是知道的为好至于开篇问题 5文件名最长多长。实际上Linux操作系统就是为了避免程序员不节制地使用长文件名强加了个限制不得超过 255 byte。另外大家有没有经验在目录下文件很多的时候我们使用ls命令时会很慢。现在大家知道原因了吧这时实际上操作系统在读取当前目录的所有 block 如果 block 比较多的话可能得需要多次 IO 操作才能完成这个简单的 ls 命令。我在自己的电脑某个目录下创建了一 100W 个空文件ls 命令 1 分钟还没出结果被我 ctrlc 掉了。在自己的项目中可不要这么干虽然操作系统可以 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 为单位的。哪怕你只向操作系统发起读取文件的 2 Byte但是操作系统会一次性给你读取 4KB 回来。因此磁盘 IO 真的是很慢而且我们只要访问了这 2 Byte确实很有可能接下来继续访问这 2byte 后面的内容这也就是程序局部性原理所以操作系统索性一次性就多读取些回来了。呵呵这就是开篇问题9的答案。这就像我们去逛超市逛一次真的是很浪费时间这可要比坑爹的磁盘 IO 也慢许多了。我们总不会逛了一圈超市就买了一个苹果就回来了吧我们肯定会多买些东西为家里以后的需求准备着反正买一堆东西比买一个苹果也没多花多少时间何乐为不为呢就是这个道理。再说说开篇问题 10我们攻城狮怎么样设计你的文件能提高一些 IO 速度呢那就是如果你知道你的要新建的文件大概会占用多大的空间的话比如 1M。那么你新建文件时就顺便和操作系统说一下让它帮你将文件的 size 预留下来。这样实际上操作系统时会尽可能为你分配连续的 block这样你再读取这个文件时磁头就省去很多寻道时间了IO 速度就显得快多了。三、写在后面的话前面我们说的都是基于我自己的文件系统情形是一个 block size 是 4KB一个 inode size 是 256byte包括我虚拟机上的 inode 数量才只有 140 多万个。这些值实际上不是固定的你完全可以在格式化你的硬盘的时候设置成其它的值。设置的原则就是看你的硬盘的容量以及你的用途。如果你的文件都是大于 4KB甚至是几 M几 G 的文件那么建议你的 block 还是尽可能的大一点吧这样 inode 里就能少记几个地址。如果你的文件大部分都是1K以下的那么确实使用4K的block会造成一点点浪费如果你的老板对成本要求异常苛刻的话你可以适当考虑把你的 block 设置得小一点。另外要关注你的文件系统的 inode。操作系统在查看目录和文件占用的磁盘空间信息时把inode节点的占用给隐藏起来了其用意在于为用户提供一个白盒的环境把数据占用的空间交给我们来认知而把 inode 信息隐藏起来为了降低我们理解操作系统的难度。而实际上我们作为非普通用户的开发人员应该具备这个知情权。这个东东直接关系到你文件系统能创建文件数量。否则哪天等你发现线上机器磁盘还剩大把大把的空间但就是 inode 使用光了那时候就只有重新格式化或者迁移服务器了。这两个操作想想都觉得苦逼啊还是能避免就尽量避免吧。思考题我们大家有个经验就是目录下小文件太多的情况下往其它地方拷贝的话速度会非常的慢我们这时往往会把目录压缩一下再拷贝。现在你能说出这样做为什么会快吗最后我想再多说一句这篇九年的时写的文章现如今看起来还是很有实用价值。由此可见内功知识的生命周期是非常之长的。反观我练过的外功比如 PHPJquery等开发知识大部分都快要过时了。这是我为什么开创「开发内功修炼」这个公众号带大家一起练内功的重要原因。好好锻炼内功技术是你对抗技术更新换代缓解中年焦虑的良药之一。推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~嵌入式Linux微信扫描二维码关注我的公众号