最快的文件访问/存储?

时间:2009-11-07 06:06:18

标签: file storage

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

将其想象为哈希表,只有哈希键是文件名,关联值是文件的数据。

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

有什么想法吗?

这方面的关键是找到文件。查找文件按名称打开的最快方法是什么?

编辑:

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

    我想提出几个彻底的答案,不管它们是否是正确的,而且因为我的新手状态而不能。对不起伙计们!

    10 个答案:

    答案 0 :(得分:2)

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

    您可能还想考虑将关系数据库用于此类事情。 7.5亿行是一种中型数据库,因此任何强大的DBMS(例如PostgreSQL)都能够很好地处理它。您也可以在数据库中存储任意blob,因此无论您要将哪些内容存储在磁盘上的文件中,您都可以将其存储在数据库中。

    更新:您的其他信息当然有用。给定FAT32和NTFS之间的选择,然后肯定选择NTFS。不要在一个目录中存储太多文件,100,000可能是一个需要考虑的上限(尽管你必须进行实验,没有硬性规定)。你朋友对每个字母的新目录的建议可能太多了,你可以考虑在每四个字母或其他东西上分解它。选择的最佳值取决于数据集的形状。

    分解名称的原因是一个好主意,通常文件系统的性能会随着目录中文件数量的增加而降低。这在很大程度上取决于正在使用的文件系统,例如FAT32将是可怕的,每个目录可能只有几千个文件。您不希望将文件名分解为,因此您将最大限度地减少文件系统必须执行的目录查找次数。

    答案 1 :(得分:2)

    该文件算法将起作用,但它不是最佳的。我认为使用2或3个字符“段”会更好地表现 - 特别是当你开始考虑做备份时。

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

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

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

    1. 无需数据库访问。
    2. 文件将分布在许多目录中。如果你没有将它们展开,你将遇到严重的性能问题。 (我模糊地回忆起有人在一个文件夹中发现了大约40,000个文件的问题,但我对这个数字没有信心。)
    3. 无需搜索文件。您可以从文件名中找出文件的确切位置。
    4. 简单。您可以非常轻松地将此算法移植到几乎任何语言。
    5. 这也有一些缺点:

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

    答案 2 :(得分:1)

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

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

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

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

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

    更新:

    鉴于您的更新,是否可以整合一些文件? 1k文件的存储效率不高,因为文件系统(fat32,ntfs)具有簇大小,并且每个文件都将使用簇大小,即使它小于簇大小。每个文件夹中的文件数量通常都有限制,但存在性能问题。您可以通过在文件夹中放入多达10k个文件来查看性能下降的程度来进行简单的基准测试。

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

    答案 3 :(得分:1)

    这在很大程度上取决于您要将文件存储在哪个文件系统上。文件系统处理大量文件的能力差异很大。

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

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

    另外,我会以整个名称存储文件本身,如果需要,这也可以更容易手动遍历此目录结构。

    所以,我会将 foobar.txt 存储为 f / o / o / b / foobar.txt

    答案 4 :(得分:1)

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

    所以你必须将几个文件分组到一个物理文件中。 1个存储文件中的1024个文件似乎合理。要在这些存储文件中找到单个文件,您必须使用一些RDBMS(提到PostgreSQL并且它很好,但SQLite可能更适合这个)或类似的结构来进行映射。

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

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

    答案 5 :(得分:0)

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

    答案 6 :(得分:0)

    为什么不在数据库表中存储路径?

    答案 7 :(得分:0)

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

    答案 8 :(得分:0)

    我会查看hadoops型号。

    P

    答案 9 :(得分:0)

    我知道这已经晚了几年,但也许这可以帮助下一个人......

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

    希望有人帮助。 :)