我想知道在现代 Linux 计算机集群中同时访问数千个类似大小的文件的最有效方法是什么。
我对每一个文件都进行了索引操作,因此在要索引的文件旁边会生成 4 个索引文件,它们的大小大约比数据文件小 5-10 倍。
./00/00/00
现在我正在使用从到的目录层次结构./99/99/99
,并在每个目录的末尾放置一个文件,
例如./00/00/00/file000000.ext
到./99/99/99/file999999.ext
。
这似乎比在同一个目录中存放数千个文件效果更好,但我想知道是否有更好的方法来布局文件以改善访问。
答案1
ext[34] 上大型目录的一个常见性能问题是它对目录条目进行哈希处理,并按哈希顺序存储它们。这样可以快速解析特定名称,但实际上会随机化名称的列出顺序。如果您尝试对目录中的所有文件进行操作,并仅按列出顺序迭代每个条目,则会导致大量随机 IO,这非常慢。解决此问题的方法是按 inode 编号对目录列表进行排序,然后按从最低到最高的 inode 编号的顺序循环遍历文件。这可以使您的 IO 基本保持连续。
答案2
一种常用的方案是使用文件的哈希值重命名文件,同时保留扩展名并使用前几个字符将它们存储在不同的文件夹中。
例如:
md5(test.jpg)为您提供“13edbb5ae35af8cbbe3842d6a230d279”
您的文件将被命名为“13edbb5ae35af8cbbe3842d6a230d279.jpg”并将其存储在./13/ed/bb/5ae35af8cbbe3842d6a230d279.jpg,这样,给定大量文件,您应该每个文件夹的文件分布良好。
您最终会得到一个与您的类似的树,但更轻(元数据方面),因为您只需存储原始文件名及其哈希值(从哈希值构建的路径)。
作为副作用(在开发中必须考虑到),您将自动获得基于文件的重复数据删除。
此外,如果您在存储文件之前生成哈希,您还可以获得免费的错误检查。例如,您可以想象编写一个小的 cronjob 来以这种方式检查备份的完整性。
答案3
一个ServerFault 上接受的答案经过伊格纳西奥·巴斯克斯·艾布拉姆斯说
假设您有一个支持 dir_index 功能的发行版,那么您可以轻松地在一个目录中拥有 200,000 个文件。不过,为了安全起见,我会将其保持在 25,000 个左右。如果没有 dir_index,请尝试将其保持在 5,000 个。
我认为这是建议
./000/file000000 to ./000/file000999
./001/file001000 to ./001/file001999
...
./999/file999000 to ./999/file999999
目录结构的大小永远不会缩小,因此如果目录包含的文件太多,以至于其大小变得无法使用,则删除或移动该目录中的文件不会提高该目录的性能。因此,请始终从新目录开始(如有必要,重命名过大的目录、创建新目录、移动文件、删除旧目录)
现在默认的是带有 dir_index 的 ext3,这使得搜索大型目录变得非常快。
一位评论者说
ext3 中一个目录中的子目录数量限制约为 32K,但 OP 谈论的是图像文件。启用 Dir Index 的 ext3 文件系统中文件数量没有(实际的?)限制。
我想我会进行一些测试,看看将文件组织到子目录中除了性能之外是否还有其他好处ls
。优化的一般规则:1 不要,2 真的不要,3 衡量。