【问题标题】:Sorting gigantic binary files with C#使用 C# 对巨大的二进制文件进行排序
【发布时间】:2011-11-28 03:03:18
【问题描述】:

我有一个大约 400 GB 大小的大文件。由外部封闭系统每天生成。它是一个二进制文件,格式如下:

byte[8]byte[4]byte[n]

其中 n 等于 byte[4] 的 int32 值。

此文件没有分隔符,要读取整个文件,您只需重复直到 EOF。每个“项目”表示为 byte[8]byte[4]byte[n]。

文件看起来像

byte[8]byte[4]byte[n]byte[8]byte[4]byte[n]...EOF

byte[8] 是一个 64 位数字,表示由 .NET Ticks 表示的时间段。我需要对这个文件进行排序,但似乎找不到最快的方法。

目前,我将 Ticks 加载到一个结构中,并将 byte[n] 开始和结束位置并读取到文件的末尾。之后,我按 Ticks 属性对内存中的 List 进行排序,然后打开 BinaryReader 并按 Ticks 顺序查找每个位置,读取 byte[n] 值,然后写入外部文件。

在这个过程的最后,我得到了一个排序的二进制文件,但它需要永远。我正在使用 C# .NET 和一个非常强大的服务器,但磁盘 IO 似乎是个问题。

服务器规格:

  • 2x 2.6 GHz Intel Xeon(Hex-Core with HT)(24 线程)
  • 32GB 内存
  • 500GB RAID 1+0
  • 2TB RAID 5

我浏览了整个互联网,只能找到一个大文件为 1GB 的示例(让我发笑)。

有人有什么建议吗?

【问题讨论】:

  • 我不确定我是否理解您如何在只有 500GB RAID 磁盘的系统上读取一个 400GB 文件并写入另一个已排序的 400GB 文件,但 Greg 的建议听起来不错,尽管我没有亲自处理这么大的文件。
  • 嘿,我还有 2TB RAID 5。

标签: c# binary binaryfiles large-data


【解决方案1】:

加速这种文件访问的好方法是memory-map the entire file into address space,让操作系统负责从文件中读取它需要的任何位。所以做你现在做的同样的事情,除了从内存中读取而不是使用BinaryReader/seek/read。

你有很多主内存,所以这应该提供相当好的性能(只要你使用 64 位操作系统)。

【讨论】:

  • 感谢您的快速回复! MemoryMappedFile 是否能够处理 400GB 的文件?我是否需要创建不同类型的视图访问器(随机访问与顺序)?再次感谢! :)
  • MemoryMappedFile 应该能够一次性处理所有文件。我已经在 FreeBSD 上使用 Python 完成了这项工作,文件大小为 30 GB,但我完全希望它可以在 Windows 上以您的文件大小正常工作。我不确定访问器之间的区别,但任何一个都可能工作。您将按顺序读取文件一次,然后在排序后以随机顺序读取它。
【解决方案2】:

使用归并排序。 它是在线的并且很好地并行化。

http://en.wikipedia.org/wiki/Merge_sort

【讨论】:

    【解决方案3】:

    如果您可以学习 Erlang 或 Go,它们可能会非常强大并且扩展性非常好,因为您有 24 个线程。利用异步 I/O。合并排序。 由于您有 32GB 的 RAM,请尝试将尽可能多的加载到 RAM 中并在那里对其进行排序,然后再写回磁盘。

    【讨论】:

      【解决方案4】:

      我会分几次这样做。在第一次通过时,我会创建一个刻度列表,然后将它们均匀地分配到许多(数百个?)桶中。如果您提前知道刻度是均匀分布的,则可以跳过此初始通道。在第二次通过时,我会将记录拆分为这几百个大小大致相同的单独文件(这些小得多的文件代表按您想要的顺序排列的刻度组)。然后我会在内存中分别对每个文件进行排序。然后连接文件。

      它有点类似于哈希排序(我认为)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-15
        • 2019-09-06
        • 2017-02-02
        • 2021-12-16
        • 2011-07-11
        • 2019-04-20
        • 2015-09-03
        • 2021-02-07
        相关资源
        最近更新 更多