Chr*_*ell 21 linux command-line ubuntu ext4
大约有 1500 万个文件要移动,有些可能是重复的(我不想覆盖重复的)。
使用的命令(来自源目录)是:
ls -U |xargs -i -t mv -n {} /mnt/archive/targetDir/{}
Run Code Online (Sandbox Code Playgroud)
这已经按预期持续了几天,但我收到了增加频率的错误。当它开始时,目标驱动器大约为 70%,现在大约为 90%。过去大约有 1/200 的动作会出现状态和错误,现在大约是 1/5。没有一个文件超过 100Mb,大多数都在 100k 左右
一些信息:
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdb3 155G 5.5G 142G 4% /
none 4.0K 0 4.0K 0% /sys/fs/cgroup
udev 3.9G 4.0K 3.9G 1% /dev
tmpfs 797M 2.9M 794M 1% /run
none 5.0M 4.0K 5.0M 1% /run/lock
none 3.9G 0 3.9G 0% /run/shm
none 100M 0 100M 0% /run/user
/dev/sdb1 19G 78M 18G 1% /boot
/dev/mapper/archive-lvarchive 18T 15T 1.8T 90% /mnt/archive
/dev/sda1 4.6T 1.1T 3.3T 25% /mnt/tmp
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sdb3 10297344 222248 10075096 3% /
none 1019711 4 1019707 1% /sys/fs/cgroup
udev 1016768 500 1016268 1% /dev
tmpfs 1019711 1022 1018689 1% /run
none 1019711 5 1019706 1% /run/lock
none 1019711 1 1019710 1% /run/shm
none 1019711 2 1019709 1% /run/user
/dev/sdb1 4940000 582 4939418 1% /boot
/dev/mapper/archive-lvarchive 289966080 44899541 245066539 16% /mnt/archive
/dev/sda1 152621056 5391544 147229512 4% /mnt/tmp
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
mv -n 747265521.pdf /mnt/archive/targetDir/747265521.pdf
mv -n 61078318.pdf /mnt/archive/targetDir/61078318.pdf
mv -n 709099107.pdf /mnt/archive/targetDir/709099107.pdf
mv -n 75286077.pdf /mnt/archive/targetDir/75286077.pdf
mv: cannot create regular file ‘/mnt/archive/targetDir/75286077.pdf’: No space left on device
mv -n 796522548.pdf /mnt/archive/targetDir/796522548.pdf
mv: cannot create regular file ‘/mnt/archive/targetDir/796522548.pdf’: No space left on device
mv -n 685163563.pdf /mnt/archive/targetDir/685163563.pdf
mv -n 701433025.pdf /mnt/archive/targetDir/701433025.pd
Run Code Online (Sandbox Code Playgroud)
我发现很多关于这个错误的帖子,但预测不合适。诸如“您的驱动器实际上已满”或“您的 inode 已用完”甚至“您的 /boot 卷已满”之类的问题。但是,大多数情况下,他们处理由于处理文件的方式而导致问题的 3rd 方软件,并且它们都是恒定的,这意味着每次移动都会失败。
谢谢。
编辑:这是一个示例失败和成功的文件:
失败(仍在源驱动器上)
ls -lhs 702637545.pdf
16K -rw-rw-r-- 1 myUser myUser 16K Jul 24 20:52 702637545.pdf
Run Code Online (Sandbox Code Playgroud)
成功(在目标卷上)
ls -lhs /mnt/archive/targetDir/704886680.pdf
104K -rw-rw-r-- 1 myUser myUser 103K Jul 25 01:22 /mnt/archive/targetDir/704886680.pdf
Run Code Online (Sandbox Code Playgroud)
此外,虽然并非所有文件都失败,但失败的文件总是会失败。如果我一遍又一遍地重试它是一致的。
编辑:@mjturner 每个请求的一些额外命令
$ ls -ld /mnt/archive/targetDir
drwxrwxr-x 2 myUser myUser 1064583168 Aug 10 05:07 /mnt/archive/targetDir
$ tune2fs -l /dev/mapper/archive-lvarchive
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name: <none>
Last mounted on: /mnt/archive
Filesystem UUID: af7e7b38-f12a-498b-b127-0ccd29459376
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr dir_index filetype needs_recovery extent 64bit flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 289966080
Block count: 4639456256
Reserved block count: 231972812
Free blocks: 1274786115
Free inodes: 256343444
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 2048
Inode blocks per group: 128
RAID stride: 128
RAID stripe width: 512
Flex block group size: 16
Filesystem created: Thu Jun 25 12:05:12 2015
Last mount time: Mon Aug 3 18:49:29 2015
Last write time: Mon Aug 3 18:49:29 2015
Mount count: 8
Maximum mount count: -1
Last checked: Thu Jun 25 12:05:12 2015
Check interval: 0 (<none>)
Lifetime writes: 24 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 3ea3edc4-7638-45cd-8db8-36ab3669e868
Journal backup: inode blocks
$ tune2fs -l /dev/sda1
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name: <none>
Last mounted on: /mnt/tmp
Filesystem UUID: 10df1bea-64fc-468e-8ea0-10f3a4cb9a79
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 152621056
Block count: 1220942336
Reserved block count: 61047116
Free blocks: 367343926
Free inodes: 135953194
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 732
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 4096
Inode blocks per group: 256
Flex block group size: 16
Filesystem created: Thu Jul 23 13:54:13 2015
Last mount time: Tue Aug 4 04:35:06 2015
Last write time: Tue Aug 4 04:35:06 2015
Mount count: 3
Maximum mount count: -1
Last checked: Thu Jul 23 13:54:13 2015
Check interval: 0 (<none>)
Lifetime writes: 150 MB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: a266fec5-bc86-402b-9fa0-61e2ad9b5b50
Journal backup: inode blocks
Run Code Online (Sandbox Code Playgroud)
ste*_*eve 26
dir_index您在目标文件系统上使用的 ext4 功能实现中的错误。
解决方案:重新创建没有 dir_index 的文件系统。或者使用 tune2fs 禁用功能(需要一些注意事项,请参阅相关链接Novell SuSE 10/11:在 ext3 文件系统上禁用 H 树索引,尽管与ext3 相关,但可能需要类似的注意事项。
(get a really good backup made of the filesystem)
(unmount the filesystem)
tune2fs -O ^dir_index /dev/foo
e2fsck -fDvy /dev/foo
(mount the filesystem)
Run Code Online (Sandbox Code Playgroud)
ext4 有一个名为 dir_index 的特性默认启用,它很容易受到散列冲突的影响。
......
ext4 有可能散列其内容的文件名。这提高了性能,但有一个“小”问题:当 ext4 开始填满时,它的哈希表不会增长。相反,它返回 -ENOSPC 或“设备上没有剩余空间”。
用于存储大量小文件的优于 ext4 选择的建议:
如果您将文件系统用作对象存储,您可能需要考虑使用专门用于此的文件系统,这可能会损害其他特性。快速谷歌搜索找到Ceph,它似乎是开源的,可以作为 POSIX 文件系统挂载,但也可以通过其他 API 访问。我不知道在不利用复制的情况下是否值得在单个主机上使用。
另一个对象存储系统是OpenStack 的 Swift。它的设计文档说它将每个对象存储为一个单独的文件,元数据在 xattrs 中。这是一篇关于它的文章。 他们的部署指南说他们发现 XFS 为对象存储提供了最佳性能。因此,即使工作负载不是 XFS 最擅长的,但在 RackSpace 进行测试时,它显然比竞争对手更好。可能 Swift 偏爱 XFS,因为 XFS 对扩展属性有良好/快速的支持。如果不需要额外的元数据(或者如果它保存在二进制文件中),那么 ext3/ext4 可能可以在单个磁盘上作为对象存储后端运行。
Swift 为你做复制/负载平衡,并建议你给它在原始磁盘上制作的文件系统,而不是 RAID。它指出它的工作负载对于 RAID5 来说本质上是最坏的情况(如果我们谈论的是写入小文件的工作负载,这是有道理的。XFS 通常不会完全将它们打包,因此您不会获得全条带写入,并且 RAID5 必须进行一些读取以更新奇偶校验条带。Swift 文档还谈到每个驱动器使用 100 个分区。我认为这是一个 Swift 术语,并不是在谈论在每个驱动器上制作 100 个不同的 XFS 文件系统SATA 磁盘。
为每个磁盘运行一个单独的 XFS 实际上是一个巨大的差异。每个磁盘将有一个单独的 XFS 和单独的空闲列表,而不是一个巨大的空闲 inode 映射。此外,它避免了小写的 RAID5 惩罚。
如果您的软件已经构建为直接使用文件系统作为对象存储,而不是通过像 Swift 这样的东西来处理复制/负载平衡,那么您至少可以避免将所有文件放在一个目录中。(我没有看到 Swift 文档说他们如何将文件布置到多个目录中,但我确定他们确实这样做了。)
对于几乎任何普通的文件系统,使用类似的结构都会有所帮助
1234/5678 # nested medium-size directories instead of
./12345678 # one giant directory
Run Code Online (Sandbox Code Playgroud)
大约 10k 个条目是合理的,因此采用分布良好的 4 个对象名称字符并将它们用作目录是一个简单的解决方案。它不必非常平衡。奇怪的 100k 目录可能不会是一个明显的问题,一些空目录也不会。
XFS不适用于大量小文件。它尽其所能,但它针对较大文件的流式写入进行了更优化。不过,它总体上非常适合一般用途。它ENOSPC在其目录索引 (AFAIK)中没有冲突,并且可以处理一个包含数百万个条目的目录。(但最好至少使用一层树。)
Dave Chinner对分配了大量 inode 的 XFS 性能发表了一些评论,导致touch性能缓慢。寻找要分配的空闲 inode 开始花费更多的 CPU 时间,因为空闲 inode 位图变得碎片化。请注意,这不是一个大目录与多个目录的问题,而是整个文件系统上许多使用的 inode 的问题。将文件拆分到多个目录有助于解决一些问题,例如 ext4 在 OP 中阻塞的问题,但不是跟踪可用空间的整个磁盘问题。与 RAID5 上的巨型 XFS 相比,Swift 的每个磁盘的单独文件系统对此有所帮助。
我不知道btrfs是否擅长于此,但我认为可能是。我认为 Facebook 聘用其首席开发人员是有原因的。:P 我见过的一些基准测试,比如解压 Linux 内核源代码,显示 btrfs 做得很好。
我知道reiserfs已针对这种情况进行了优化,但几乎不再维护。我真的不建议使用 reiser4。不过,尝试一下可能会很有趣。但它是迄今为止最不经得起未来考验的选择。我还看到过旧的 reiserFS 性能下降的报告,并且没有好的碎片整理工具。( google filesystem millions of small files,并查看一些现有的 stackexchange 答案。)
我可能遗漏了一些东西,所以最后的建议是:在 serverfault 上询问这个问题! 如果我现在必须选择某些东西,我会说尝试一下 BTRFS,但要确保你有备份。(特别是如果你使用 BTRFS 的内置多磁盘冗余,而不是在 RAID 之上运行它。性能优势可能很大,因为小文件对于 RAID5 来说是个坏消息,除非它是一个以读取为主的工作负载。)