输入为千兆/太字节大小时会发生什么变化?

时间:2010-06-10 06:34:47

标签: python large-data-volumes scientific-computing

今天我刚刚迈出真正的科学计算,今天我看到了一个数据集,其中最小的文件是48000个字段到1600行(几个人的单倍型,22号染色体)。这被认为很小。

我写Python,所以我花了最近几个小时阅读有关HDF5,Numpy和PyTable的内容,但我仍然觉得我并不是真的想知道一个太字节大小的数据集对我来说实际意味着什么程序员。

例如,有人指出,对于较大的数据集,不可能将整个内容读入内存,不是因为机器内存不足,而是因为架构的地址空间不足!它引起了我的注意。

我在课堂上依赖的其他假设是什么?我需要做些什么才能开始做或以不同的方式思考? (这不一定是Python特定的。)

4 个答案:

答案 0 :(得分:18)

我目前正在石油行业的一个小角落从事高性能计算,并定期处理您所关注的数量级的数据集。以下是需要考虑的一些要点:

  1. 数据库在这个领域没有很大的吸引力。几乎所有数据都保存在文件中,其中一些文件基于70年代设计的磁带文件格式。我认为不使用数据库的部分原因是历史性的; 10年前,甚至5年前,我认为甲骨文及其亲属根本无法管理O(TB)的单一数据集,更不用说拥有1000个此类数据集的数据库了。

    另一个原因是有效数据库分析和设计的规范化规则与科学数据集的性质之间存在概念上的不匹配。

    我认为(虽然我不确定)今天表现原因的说服力要低得多。由于现有的大多数主要数据库都可以处理空间数据集,而这些空间数据集通常与其他科学数据集的概念更接近,因此概念不匹配的原因可能也不那么迫切。我已经看到越来越多地使用数据库来存储元数据,然后对包含传感器数据的文件进行某种引用。

    然而,我实际上仍在关注HDF5。它对我来说有几个吸引力(a)它只是另一种文件格式,所以我不需要安装DBMS并且必须解决它的复杂性,并且(b)使用合适的硬件我可以并行读/写HDF5文件。 (是的,我知道我也可以并行读写数据库。)

  2. 这让我想到了第二点:在处理非常大的数据集时,你真的需要考虑使用并行计算。我主要在Fortran工作,它的一个优点是它的数组语法很适合很多科学计算;另一个是对可用的并行化的良好支持。我相信Python也有各种并行化支持,所以对你来说这可能不是一个糟糕的选择。

    当然,您可以在顺序系统上添加并行性,但开始设计并行性要好得多。举一个例子:问题的最佳顺序算法通常不是并行化的最佳候选者。您可能最好使用不同的算法,在多个处理器上可以更好地扩展。这很好地引导到下一点。

  3. 我认为你可能不得不放弃将你拥有的任何附件(如果有的话)交给许多聪明的算法和数据结构,这些算法和数据结构在所有数据驻留在内存中时都能正常工作。经常尝试使它们适应无法将数据同时存入内存的情况,比蛮力更难(并且性能更低)并且将整个文件视为一个大型阵列。

    < / LI>
  4. 性能开始严重影响,无论是程序的执行性能还是开发人员的性能。并不是1TB数据集需要的代码是1GB数据集的10倍,因此您需要更快地工作,这就是您需要实现的一些想法将会非常复杂,并且可能必须由域专家编写,即你正在与之合作的科学家。这里的域专家用Matlab编写。

  5. 但这种情况持续太久,我最好还是回去工作

答案 1 :(得分:5)

简而言之,IMO的主要区别是:

  1. 你应该事先知道你的可能性 瓶颈将是(I / O或CPU)并专注于最佳算法和基础设施 解决这个问题。 I / O经常是瓶颈。
  2. 算法的选择和微调通常支配任何其他选择。
  3. 即使对算法和访问模式进行适度更改也会影响性能 数量级。你将进行微观优化。 “最佳”解决方案将是 取决于系统。
  4. 与您的同事和其他科学家交谈,从中获益 数据集。在教科书中找不到很多技巧。
  5. 预先计算和存储非常成功。
  6. 带宽和I / O

    最初,带宽和I / O通常是瓶颈。为了给你一个观点:在SATA 3的理论极限下,读取1 TB需要大约30分钟。如果您需要随机访问,多次阅读或写入,您希望在大多数情况下在内存中执行此操作或者需要更快的内容(例如iSCSIInfiniBand)。理想情况下,您的系统应能parallel I/O尽可能接近您使用的任何接口的理论极限。例如,只需在不同的进程中并行访问不同的文件,或HDF5之上的MPI-2 I/O非常常见。理想情况下,您还可以并行执行计算和I / O,以便其中一个“免费”。

    <强>集群

    根据您的情况,I / O或CPU可能不是瓶颈。无论它是哪一个,如果您可以有效地分配任务(例如MapReduce),群集可以实现巨大的性能提升。这可能需要与典型的教科书示例完全不同的算法。在这里花费开发时间通常是花费的最佳时间。

    <强>算法

    在算法之间进行选择时,算法的大O非常重要,但具有相似大O的算法在性能上可能会因地点而异。算法本地越少(即,更多的高速缓存未命中和主要内存未命中),性能越差 - 访问存储通常比主存储器慢一个数量级。对于矩阵乘法或tiling,改进的经典示例为loop interchange

    计算机,语言,专业工具

    如果您的瓶颈是I / O,这意味着大数据集的算法可以受益于更多的主存储器(例如64位)或具有更少内存消耗的编程语言/数据结构(例如,在Python __slots__中可能有用),因为更多的内存可能意味着每个CPU时间的I / O更少。顺便说一句,具有主存储器TB的系统并非闻所未闻(例如HP Superdomes)。

    同样,如果您的瓶颈是CPU,那么允许您使用架构特殊功能的更快的机器,语言和编译器(例如SIMD SSE)可能会使性能提高一个数量级

    您查找和访问数据以及存储元信息的方式对于提高性能非常重要。您通常会使用平面文件或特定于域的非标准软件包来存储数据(例如,不是直接关系数据库),以便您更有效地访问数据。例如,kdb+是用于大型时间序列的专用数据库,ROOT使用TTree对象有效地访问数据。你提到的pyTables将是另一个例子。

答案 2 :(得分:1)

虽然某些语言在类型中的内存开销自然低于其他语言,但这对于此大小的数据来说无关紧要 - 无论您使用哪种语言,都不会将整个数据集保存在内存中,因此Python的“费用”在这里无关紧要。正如您所指出的那样,根本没有足够的地址空间来引用所有这些数据,更不用说保留它了。

这通常意味着:a)将数据存储在数据库中,或b)以附加计算机的形式添加资源,从而增加可用的地址空间和内存。实际上,你最终会做这两件事。使用数据库时要记住的一个关键因素是数据库不仅仅是在您不使用数据时放置数据的地方 - 您可以在数据库中进行工作,您应该尝试这样做。您使用的数据库技术对您可以执行的工作类型有很大影响,但是,例如,SQL数据库非常适合进行大量的数学运算并有效地执行(当然,这意味着模式设计变为整体架构中非常重要的一部分)。不要只是在内存中吸取数据并对其进行操作 - 尝试利用数据库的计算查询功能,在将数据放入进程的内存之前,尽可能多地完成工作。

答案 3 :(得分:0)

主要假设是关于单个机器中可接受价格的cpu / cache / ram / storage / bandwidth的数量。 stackoverflow上有很多答案仍然基于具有4G内存和大约1TB存储和1Gb网络的32位机器的旧假设。使用16GB DDR-3 ram模块,220欧元,512 GB RAM,48台核心机器可以合理的价格建造。从硬盘到SSD的转换是另一个重要的变化。