V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Tiande
V2EX  ›  Linux

“Linux 的文件系统(ext4)会将文件分散在整个磁盘,在文件之间留有大量的自由空间”?!

  •  
  •   Tiande ·
    Tiande · 2015-04-17 16:41:38 +08:00 · 7495 次点击
    这是一个创建于 3509 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、标题那句话对吗?
    原文:为什么Linux不需要碎片整理?

    查了其他资料,没看到提及 文件分散在整个磁盘 的。有额外资料可以提供吗?

    难道
    $ mkdir dir1/ dir2/
    他们的 inode 可能会随机分散到磁盘的不同位置?!
    这样存储数据,对机械硬盘来说,读写速度都会减慢吧,即使人察觉不到。

    二、在 挂载点的意义 这一节里

    /, /boot, /home 为三个不同的 filesystem
    [root@www ~]# ls -lid / /boot /home
    2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
    2 drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot
    2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home

    看到了吧!由于 filesystem 最顶层的目录之 inode 一般为 2 号,因此可以发现 /, /boot, /home 为三个不同的 filesystem 啰! (因为每一行的文件属性并不相同,且三个目录的挂载点也均不相同之故。)

    一个文件占用一个 inode ,挂载的三个 filesystem 不是 三个 文件吗,只占用了一个 inode 2?

    .˚‧º·(இωஇ)‧º·˚. 我是不是要滚回去重修了 -(:3」∠)-

    23 条回复    2015-04-24 16:39:37 +08:00
    rrfeng
        1
    rrfeng  
       2015-04-17 16:57:25 +08:00   ❤️ 1
    文件系统的根目录 inode = 2

    /, /home, /boot 是三个文件系统,是不同的 2 。

    第一个问题我所了解的仅仅是 ext4 在存储文件的时候,可以预留空间,也就是说比如先存入 A 文件 12K,但是会自动在 A 的后面预留 N 长度的磁盘空间,以用于 A 文件可能会变大。再次存入 B 文件时,会从 A 文件起始位置 12K + N 位置开是写入。

    具体的看 ext4 实现?
    notnumb
        2
    notnumb  
       2015-04-17 17:20:02 +08:00   ❤️ 1
    码农懂点硬件和还是有好处,这链接的文章就是意淫,太TM外行了。
    search ext4 online defrag
    只要是随机存储器,程序优化的再好,都会有碎片,那你觉得内存会不会有碎片呢?
    Tiande
        3
    Tiande  
    OP
       2015-04-17 17:34:22 +08:00 via iPhone
    @rrfeng inode 是算在文件系统里的呐,误解成以一个硬盘为单位了。
    Tiande
        4
    Tiande  
    OP
       2015-04-17 17:45:51 +08:00 via iPhone
    @notnumb 百度谷歌出的中文搜索结果,都是这种荒诞的言论。感觉 unix-like 类的操作系统完全被 Apple 代言了。
    内存如何不懂,但机械硬盘注定会出现“碎片”,没人能保证每个文件总是在连着的 data block 内。
    wy315700
        5
    wy315700  
       2015-04-17 17:50:10 +08:00   ❤️ 1
    请想清楚碎片的定义,比如一个分区有100个inode,编号1-100.

    文件A 在1-10,文件B在50-60,这就不叫碎片。
    文件A是1-5,7-11,文件B是6,50-59,这才叫碎片

    FAT时代,磁盘是从前往后写的,比如 文件A写了1,文件B会从2开始写。

    NTFS和EXT,新建文件的时候,会重新从后面找一段相对比较长的区域,比如文件A占了1以后文件B不会从2开始,而是可能从10,或者50这些地方开始,这是避免出现碎片的方法。

    解释完毕,不知道有没有听懂。
    Khlieb
        6
    Khlieb  
       2015-04-17 18:20:18 +08:00 via Android   ❤️ 1
    @dtdnqsb 应该上果壳网、松鼠会科普一下
    cattyhouse
        7
    cattyhouse  
       2015-04-17 18:28:47 +08:00 via iPhone   ❤️ 1
    Do ext4 filesystems need to be defragmented?

    Yes (but very rarely).

    If so, how do I defragment them?

    Copy all the files off the partition, erase the files from the partition, then copy the files back onto the partition. The file system will intelligently allocate the files as you copy them back onto the disk.

    If not, could you post a simple explanation of why they do not need to be defragmented?

    ext4 acts in a more intelligent way than merely adding new files into the next available space. Instead of placing multiple files near each other on the hard disk, Linux file systems scatter different files all over the disk, leaving a large amount of free space between them. When a file is edited and needs to grow, there’s usually plenty of free space for the file to grow into. If fragmentation does occur, the file system will attempt to move the files around to reduce fragmentation in normal use, without the need for a defragmentation utility.
    extreme
        8
    extreme  
       2015-04-17 18:43:16 +08:00   ❤️ 1
    感觉楼上的都没说道重点。
    HDD是高速旋转的,数据分散储存是必然的。
    数据是存入block当中的,一个block无的大小是固定的,因此可能需要多个block才能把数据存储完毕,因此就需要记录各个文件所存储的block信息。
    FAT与NTFS是把block位置信息储存在每一个block的末尾。
    举例吧:一个数据储存需要三个block,因此,在写下一个block时(抑或写完下一个或写完全部?),就在前一个block的末尾记录下一个block的位置。
    ext则采用了inode方式,使用inode记录数据的block信息。在格式化时,会使用一部分磁盘空间作为inode区域。
    举例吧:一个数据储存需要三个block,在写完这三个block后,就往inode中写入这个数据的block信息。

    读取文件前就知道所有block的位置,明显效率比较高。
    Havee
        9
    Havee  
       2015-04-17 20:20:45 +08:00   ❤️ 1
    文章是有些不靠谱,不过碎片确实是 M$ 下带来的概念,而且文章也没说错,磁盘没被写满大部分之前,ext4 确实是不存在类似 fat 的碎片的。事实上,日志式文件系统基本都不存在所谓的碎片。
    xieyudi1990
        10
    xieyudi1990  
       2015-04-18 04:44:26 +08:00 via iPhone   ❤️ 3
    @extreme 别的我没弄过, 不过你对fat实现部分有误. fat是通过一个单独的file allocation table实现文件碎片的链式储存.

    写过fat驱动的路过.
    msg7086
        11
    msg7086  
       2015-04-18 07:22:00 +08:00   ❤️ 2
    #4 @dtdnqsb 不管什么存储,都会有碎片。就连房间里放东西也会出碎片。别说机械盘,SSD也会有的。

    #8 @extreme 你说的HDD在高速旋转,这说的是LBA以下的物理存储么?
    硬盘在初始化的时候会自动标记好每个LBA的位置以保证读取扇区的时候能跟着HDD的旋转达到最高的读取速度。
    而上文讨论说的明显是FS级,不是底层物理扇区级。
    julyclyde
        12
    julyclyde  
       2015-04-18 11:24:45 +08:00   ❤️ 1
    @msg7086 SSD上的碎片没有性能意义
    extreme
        13
    extreme  
       2015-04-18 13:33:59 +08:00
    @xieyudi1990 之前看过FAT的资料,是这样介绍的,所以照着自己的印象写了出来。搜索了下file allocation table,貌似的确如此,不过大多数表达得有点模糊。

    @msg7086 看了下,HDD貌似写入数据时是按顺序写入到磁碟的扇区中的,也就是说碎片的产生不是源于碟片的高速旋转,而是使用过程中的各种因素。

    感谢两位指点。另外,感觉越基本的东西越难找到资料,比较反感那些一堆理论的文章,我更喜欢举例,介绍其工作的步骤,这样更容易理解。
    msg7086
        14
    msg7086  
       2015-04-18 16:01:38 +08:00   ❤️ 1
    @julyclyde 是不影响性能,但是还是有碎片出现的。倒不如说SSD常年保持大量碎片

    @extreme LBA之上来看是顺序写入,LBA之下来看就不是了。
    高速旋转的碟片在读取的时候,一个扇区读完,传走以后,可能磁头已经移到三四个扇区之后了。
    所以磁盘在底层格式化的时候会设置跃点,即分隔数个的扇区连在一起,比如 1 1001 2001 3001 2 1002 2002 3002 3 这样。读完1以后磁头正好移动到2,这样来实现最高效率的读取。
    Tiande
        15
    Tiande  
    OP
       2015-04-18 16:56:13 +08:00 via iPhone
    (●°u°●)​ 安静静地看讨论
    JamesRuan
        16
    JamesRuan  
       2015-04-19 00:41:11 +08:00   ❤️ 1
    SSD也是有碎片的,但是这个不是通常意义上文件不连续造成的,而是由于芯片单元未被写满造成的。

    比如整个盘只有2个芯片单元,你写了1.1个单元和0.8个单元的时候,逻辑上还有0.1个单元空出来,而实际物理上,其中一个芯片单元被不单单被写入了两次,还在中间过程被完全擦除了一次。而我们知道,SSD的擦除速度是非常慢的,所以才需要主控芯片去保证,在磁盘没有接近满的时候,尽量别去写已经写了一部分的单元(实际也不可能维护一个完整的分配表啥的保证一定不会,只是通过算法去避免)。也有TRIM这样的硬件指令去标记哪些区域可以安全地被回收。

    而文件系统层面的allocate-on-flash机制也可以让很多小的随机写入合并为一次大的顺序写入,用extents这种鼓励使用连续空间减少碎片。

    并不是说Linux不会有碎片,只是说,碎片在磁盘快满之前,从来不会发展成一个特别严重的问题。
    有些文件系统(比如XFS)就设计有在线的碎片整理程序(xfs_fsr);我基本一年用一次,按我的使用频率,在5%的碎片文件中,即便是大文件,通常碎片化程度也在20段以内,一般文件都是个位数碎片,而95%的文件根本就没碎片。除非剩余空间很少且经常反复删除和写入,才会让文件系统碎片化累计导致性能问题。
    guorzhen
        17
    guorzhen  
       2015-04-19 08:41:33 +08:00   ❤️ 1
    Ext4 block and inode allocator improvements
    http://landley.net/kdocs/ols/2008/ols2008v1-pages-263-274.pdf
    notnumb
        18
    notnumb  
       2015-04-20 12:39:12 +08:00
    @extreme
    “HDD是高速旋转的,数据分散储存是必然的” 这句话完全忽略了磁盘芯片和kernel的配合使用的预读机制。
    这个说法也是有问题的,碟片虽然高速旋转,一般单碟硬盘读写的磁臂和磁头却只有一个
    如果过于分散,磁臂开销导致性能差
    kernel和磁盘控制器都会预读到缓存里面,普通磁盘32~128MB cache,kernel会缓存到内存
    extreme
        19
    extreme  
       2015-04-20 12:52:01 +08:00   ❤️ 1
    @notnumb 不知所云,写入你又扯上预读。
    我在13楼已经纠正了我关于碎片产生的说法了。
    还是让我来告诉你缓存是怎样工作的吧:
    硬盘读取某个特定扇区时,会读取附近扇区的数据并存入缓存当中,当需要读取的扇区的数据就是被缓存的扇区时,即可直接从缓存中输出。
    但由于碎片的关系,数据不连续,导致缓存的命中率下降。
    notnumb
        20
    notnumb  
       2015-04-20 13:42:27 +08:00   ❤️ 1
    @extreme
    讨论问题而已,但你确实说错了。承认错误没什么不对。同样我写的不一定是对的。

    反而你说的话漏洞百出

    比如这句
    “但由于碎片的关系,数据不连续,导致缓存的命中率下降”

    缓存命中率下降,是随机的IO都会导致,碎片只是表象,应该确切的说碎片导致随机的io,导致了磁臂和磁头的来回移动,从而影响延时和带宽。

    为什么预读,预读就是为了减少随机IO。相反一个程序写入顺序的数据,也会保存在临近的扇区。
    这样读取的时候才能提高命中率。提高命中率减少磁臂的移动带来的损失。
    wizardforcel
        21
    wizardforcel  
       2015-04-20 14:43:20 +08:00 via Android   ❤️ 1
    block分散,并不等于inode分散。另外,一个inode只可以描述一个文件,或者目录,但是可以关联多个block。

    不同的文件必然存在不同的block里,所以这样对读写不同文件之间没什么效率损耗。但这种储存方式使文件能最大程序的连续,读同一个文件的不同block明显变快了。
    extreme
        22
    extreme  
       2015-04-21 00:39:42 +08:00
    @notnumb 讨论?你想得太简单了,这是一场辩论。
    我已经不是第一次辩论,也不会是最后一次。

    不是我不承认错误,是你根本没说出任何有力的证据能证明我是错误的或能让我信服的东西。

    你抓住一句针对写入的话,将其判断为错误,既然你说我对写入的描述是错误的,你不是应该解释一下的吗?但你却突然扯到读取,缓存,完全不知道你想表达什么, 难道你想说你在进行“侧面描写”?
    看你20楼的回复,看了半天,一样不知道你想表达什么,你貌似想说不是碎片导致缓存命中率下降,是随机I/O,但后面又说碎片导致随机I/O,最后又说按顺序的数据可以提高缓存命中率,为什么我觉得你说了那么多,最后的意思还是和我原来说的差不多?你是想把“连续”替换为“顺序”吗?如果是,那你为什么不解释下?

    你想说我是错误的,我不反对,但既然你认为我是错误的,那就请你证明我是错误的,并作出解释。

    我可不希望看到一些解释得含糊不清,观点不明确,牛头不对马嘴的话,实在恶心人,如果你还想说这种话,那你最好立刻按下Alt with F4,不,是去把电闸拉下!
    Mr1028
        23
    Mr1028  
       2015-04-24 16:39:37 +08:00   ❤️ 1
    @dtdnqsb 我也不懂啊。。。。搞底层的好流弊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5502 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 06:00 · PVG 14:00 · LAX 22:00 · JFK 01:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.