最快的文件访问/存储?

问题描述:

我有大约750,000,000个文件需要存储在磁盘上。更重要的是,我需要能够随时访问这些文件 - 任何给定的文件 - 在最短时间内可能。我需要做些什么才能最快地访问这些文件?最快的文件访问/存储?

把它看作一个散列表,只有散列键是文件名,相关的值是文件的数据。

一位同事说,把它们组织成这样的目录:如果我想存储一个名为“foobar.txt”的文件并将它存储在D:盘上,请将文件放在“D:\ f \ o \ o \ b \一个\ r \吨\ X \ t”的。他无法解释为什么这是个好主意。这个想法有什么吗?

任何想法?

关键是找到的一个文件。按名称打开文件的最快方式是什么?

编辑:

  • 我有过在此数据被存储在文件系统的控制。这将是NTFS或FAT32。
  • 文件数据存储在数据库中不是一个选项。
  • 文件将会非常小 - 最大可能为1 kb。
  • 驱动器将变成固态。
  • 数据访问几乎是随机的,但我可能会根据请求的频率确定每个文件的优先级。有些文件将比其他文件访问得多。
  • 项目将不断添加,有时会被删除。
  • 将多个文件合并为单个文件是不切实际的,因为文件之间没有逻辑关联。
  • 我很想通过对这些东西进行测试来收集一些指标,但是这种努力可能会像项目本身一样消耗!
  • EDIT2:

    我想给予好评数透彻的答案,无论他们是斑点或没有,不能因为我的新手状态。对不起大家!

    +0

    这个数据是静态的(750mil是它)还是你添加到它(定期添加更多的文件)?它可以只读吗,还是你需要能够更新文件?它是真正的随机文件访问,还是有任何形式的访问模式,你可能会仔细观察? – Scanningcrew 2009-11-07 06:18:04

    +0

    已更新的问题来回答此问题。 (定期添加更多文件,删除文件的频率不高,访问是随机的,但有些文件会比其他文件访问得多)。 – JamesBrownIsDead 2009-11-07 06:25:15

    +0

    重新编辑您的EDIT2评论,您只需要15个代表即可投票。有关详细信息,请参阅http://*.com/faq。 – 2009-11-07 07:03:52

    单个文件之间是否有任何关系?就访问时间而言,你放入什么文件夹不会影响太多;磁盘上的物理位置是重要的。

    这听起来像是文件系统选择的问题。一种选择可能是ZFS,它是专为大批量应用而设计的。

    您可能还想考虑使用关系数据库来处理这类事情。 7.5亿行是一种中等大小的数据库,所以任何强大的DBMS(例如PostgreSQL)都能够很好地处理它。你也可以在数据库中存储任意的blob,所以无论你将要存储在磁盘上的文件中,你都可以直接存储在数据库中。

    更新:您的其他信息肯定有帮助。鉴于FAT32和NTFS之间的选择,那么肯定是选择NTFS。不要将太多文件存储在单个目录中,100,000可能是需要考虑的上限(尽管您必须进行试验,但没有硬性规定)。你的朋友对每封信的新目录的建议可能太多了,你可能会考虑在每封信的四个字母之间分解它。要选择的最佳值取决于数据集的形状。

    分解名称的原因是一个好主意,通常文件系统的性能随着目录中文件数量的增加而下降。这很大程度上取决于正在使用的文件系统,例如FAT32可能会很糟糕,每个目录可能只有几千个文件。你不想分割文件名太多,所以你会尽量减少文件系统将要做的目录查找的次数。

    +0

    数据库解决方案将运行良好,但可能不会更快。如果不先做一些测试,我会非常谨慎地猜测。通过DB索引查找文件意味着使用搜索树。基于目录的trie实现的建议解决方案还允许通过树进行Olog(n)访问,但是通过字母分解意味着您没有太多的控制权来控制节点如何拆分。文件名中的模式可能会导致巨大的节点。 – 2009-11-07 06:46:12

    +0

    对,我不会试图声称数据库会更快,但它是另一个应该考虑的选项。但是,数据库旨在处理具有任意病理模式的字符串类型的键。 :) – 2009-11-07 07:05:42

    为什么不将路径存储在数据库表中可以接受?

    我的猜测是他正在考虑在磁盘上创建一个Trie数据结构,其中节点是一个目录。

    这在很大程度上取决于很多因素:

    • 什么文件系统,您使用的?
    • 每个文件有多大?
    • 您使用的是什么类型的驱动器?
    • 什么是访问模式?

    纯粹随机访问文件在传统磁盘中非常昂贵。您可以获得的一项重大改进是使用固态驱动器。

    如果您可以推理访问模式,则可以利用引用的局部性来放置这些文件。

    另一种可能的方法是使用数据库系统,并将这些文件存储在数据库中以利用系统的缓存机制。

    更新:

    鉴于你的更新,是possbile您整合一些文件? 1k文件作为文件系统(fat32,ntfs)具有簇大小并不是非常有效,即使它小于簇大小,每个文件也会使用簇大小。每个文件夹中的文件数量通常有限制,并且性能问题。你可以做一个简单的基准测试,在一个文件夹中放置多达10k个文件,看看有多少性能下降。

    如果您设置为使用trie结构,我会建议调查文件名的分布,然后根据分布将它们分解到不同的文件夹中。

    我想看看hadoops模型。

    P

    这取决于对什么文件系统,你要的文件存储在一个大的范围。文件系统处理大量文件的能力差别很大。您的同事基本上建议使用Trie data structure。使用这样的目录结构意味着在每个目录级别只有少数文件/目录可供选择;这可能会有所帮助,因为随着目录中文件数量的增加,访问其中一个文件的时间也会增加(实际时间差异取决于文件系统类型。)

    这就是说,我个人不会去那么多深度 - 三到四级应该足以提供性能优势 - 之后的大多数级别可能会有很多条目(假设您的文件名不遵循任何特定模式)。

    另外,我会将文件本身与其全名一起存储,如果需要,这将使手动遍历该目录结构变得更容易。

    所以,我将存储foobar.txtF/O/O/B/foobar.txt

    首先,文件大小是非常小的。任何文件系统都会吃至少4倍多的空间。我的意思是磁盘上的任何文件将为1kb文件占用4kb。特别是在SSD磁盘上,4kb扇区将是常态。

    所以,你必须将几个文件到1个物理文件。 1个存储文件中的1024个文件看起来合理。要找到你必须使用一些RDBMS这些存储文件的单个文件(PostgreSQL的被提及,这是好的,但SQLite的可能是更适合这个)或类似结构进行映射。

    你的朋友建议的目录结构听起来不错,但它不能解决物理存储问题。您可以使用类似的目录结构来存储存储文件。最好用数字系统来命名它们。

    如果可以的话,不要让它们格式化为FAT32,至少NTFS或Unix最近的一些文件系统。由于文件的总大小不是那么大,NTFS可能就足够了,但ZFS是更好的选择...

    该文件算法可以工作,但它不是最优的。我认为使用2或3个字符的“段”对性能会更好 - 尤其是当您开始考虑进行备份时。

    例如:
    d:\存储\ FO \ OB \ AR \ foobar.txt

    d:\存储\ FOO \条\ foobar.txt

    有使用一些好处这种算法:

    1. 没有数据库访问是必要的。
    2. 文件将跨越多个目录铺开。如果你不把它们分散出去,你会遇到严重的性能问题。 (我隐约记得有人在一个文件夹中有大约40,000个文件的问题,但我对这个数字没有把握。)
    3. 没有必要搜索文件。您可以根据文件名确切地确定文件的位置。
    4. 简单。您可以非常方便地将此算法移植到任何语言。

    有一些下降,双方这也:

    1. 很多目录可能会导致缓慢的备份。想象一下,在这些目录上做递归差异。
    2. 可扩展性。当磁盘空间不足并需要添加更多存储空间时会发生什么?
    3. 您的文件名不能包含空格。

    我知道这是一个几年晚,但也许这可以帮助未来的家伙..

    我的建议使用SAN,映射到Z驱动其他服务器可以映射到为好。我不会选择你的朋友说的文件夹路径,而是更多地使用驱动器:\ clientid \ year \ month \ day \,如果你每天摄取超过10万个文档,那么你可以在小时内添加子文件夹如果需要,甚至可以分钟。这样,如果需要,您永远不会有超过60个子文件夹,同时一直下降到秒。将链接存储在SQL中以便快速检索和报告。这使得文件夹路径非常短,例如:Z:\ 05 \ 2004 \ 02 \ 26 \ 09 \ 55 \ filename.txt,因此您不会在整个板上遇到任何256个限制。

    希望能帮助别人。 :)