Python、PyTables、Java - 捆绑在一起

Posted

技术标签:

【中文标题】Python、PyTables、Java - 捆绑在一起【英文标题】:Python, PyTables, Java - tying all together 【发布时间】:2010-12-29 13:13:56 【问题描述】:

简而言之问题

让 Python 和 Java 相互配合的最佳方式是什么?

更详细的解释

我的情况有点复杂。我会尽量用图片和文字来解释。这是当前的系统架构:

我们有一个用 Java 编写的基于代理的建模模拟。它可以选择在本地写入 CSV 文件,也可以通过与 Java 服务器的连接远程写入 HDF5 文件。每次模拟运行都会产生超过 1 GB 的数据,我们会运行数十次模拟。我们需要能够对同一场景的多次运行(使用不同的随机种子)进行聚合,以查看一些趋势(例如,最小值、最大值、中值、平均值)。可以想象,试图移动所有这些 CSV 文件是一场噩梦。每次运行会产生多个文件,就像我说的那样,其中一些是巨大的。这就是我们一直试图转向 HDF5 解决方案的原因,在该解决方案中,一项研究的所有数据都存储在一个地方,而不是分散在几十个纯文本文件中。此外,由于它是一种二进制文件格式,与未压缩的 CSVS 相比,它应该能够节省大量空间。

如图所示,我们对模拟的原始输出数据进行的当前后处理也是在 Java 中进行的,并读取本地输出生成的 CSV 文件。这个后处理模块使用 JFreeChart 来创建一些与仿真相关的图表和图形。

问题

正如我之前提到的,随着我们从模拟中生成越来越多的数据,CSV 确实站不住脚,并且无法很好地扩展。此外,后处理代码做的比它应该做的更多,本质上是在执行一个非常非常穷人的关系数据库的工作(基于外键(唯一代理 ID)跨“表”(csv 文件)进行连接). 在这个系统中,以其他方式可视化数据也很困难(例如 Prefuse、Processing、JMonkeyEngine 获取原始数据的一些子集以在 MatLab 或 SPSS 中使用)。

解决方案?

我的团队认为我们确实需要一种过滤和查询我们拥有的数据以及执行跨表连接的方法。鉴于这是一次写入、多次读取的情况,我们真的不需要真正的关系数据库的开销;相反,我们只需要一些方法在 HDF5 文件上放置一个更好的前端。我找到了几篇关于此的论文,例如一篇描述如何使用XQuery as the query language on HDF5 files 的论文,但该论文描述了必须编写一个编译器来将 XQuery/XPath 转换为原生 HDF5 调用,这远远超出了我们的需要。 输入PyTables。它似乎完全符合我们的需要(提供两种不同的数据查询方式,通过 Python 列表理解或通过 in-kernel (C level) searches。

我设想的建议架构是这样的:

我不太确定如何将用于查询的 Python 代码、提供 HDF5 文件的 Java 代码以及对数据进行后处理的 Java 代码链接在一起.显然,我想重写大部分隐式执行查询的后处理代码,而是让优秀的 PyTables 更优雅地完成这件事。

Java/Python 选项

一个简单的谷歌搜索为communicating between Java and Python 提供了一些选项,但我对这个主题太陌生了,所以我正在寻找一些实际的专业知识和对提议的架构的批评。看起来 Python 进程应该与 Datahose 在同一台机器上运行,这样大的 .h5 文件就不必通过网络传输,而是将更小的过滤视图传输给客户端。 Pyro 似乎是一个有趣的选择——有人有这方面的经验吗?

【问题讨论】:

我对 Python 的了解不够,无法回答,但我想说这是一个文笔优美的问题。我所能提供的只是一个建议,如果您使用 Jython,您可以从 Python 调用 Java 代码和库,我相信 Jython 代码也可以从 Java 调用。此外,虽然 HDF5 是为大型数据集设计的一种出色的格式,但如果您的数据是真正的关系型数据并且您的分析很复杂,那么数据库对于简化 SQL 查询仍然更有意义。 +1 个很好的问题,非常清楚 ...也许是一个幼稚的问题,但为什么必须让 Java 与 Python 交互呢?您似乎有一个很好的分层架构,它提供了一个由您的 HDF5 文件表示的数据接口。从你的问题中我不清楚你想从 Python 中用 Java 做什么 - 反之亦然 - 以及为什么。 关系数据库不必有很高的开销。你看过类似 SQLite 的东西吗? Re: Ichorus:如果 HDF5 数据软管计划失败,我曾建议使用像 SQLite 这样的 RDBMS,但我们从来没有到实现它来​​查看它的性能的地步。当我们不需要任何行级锁定或事务功能的完整 RDBMS 时,这似乎有点矫枉过正 【参考方案1】:

这是一个史诗般的问题,有很多考虑因素。由于您没有提及任何具体的性能或架构限制,我会尽力提供最全面的建议。

使用 PyTables 作为其他元素和数据文件之间的中间层的最初计划似乎很可靠。但是,没有提到的一个设计约束是所有数据处理中最关键的约束之一:这些数据处理任务中的哪些可以以批处理方式完成,哪些数据处理任务更像是实时流。

“我们确切地知道我们的输入和输出,并且可以进行处理”(批处理)和“我们知道我们的输入以及需要什么可供其他东西询问”(实时)之间的这种区别使得一个建筑问题。查看您的图表,有几种关系暗示了不同的处理方式。

此外,在您的图表上,您有不同类型的组件都使用相同的符号。这使得分析预期的性能和效率有点困难。

另一个重要的制约因素是您的 IT 基础架构。您是否有高速网络可用存储?如果您这样做,中间文件将成为一种出色、简单且快速的在基础架构元素之间共享数据的方式,以满足所有批处理需求。您提到在运行 Java 模拟的同一台服务器上运行 PyTables-using-application。但是,这意味着服务器将承受写入和读取数据的负载。 (也就是说,仿真环境在查询数据时可能会受到无关软件需求的影响。)

直接回答您的问题:

PyTables 看起来不错。 Python 和 Java 有多种通信方式,但请考虑一种与语言无关的通信方法,以便以后如有必要可以更改这些组件。这就像找到支持 Java 和 Python 的库并尝试它们一样简单。无论如何,您选择使用任何库实现的 API 都应该是相同的。 (XML-RPC 可以很好地用于原型设计,因为它在标准库中,Google 的 Protocol Buffers 或 Facebook 的 Thrift 是很好的生产选择。但是不要低估如果数据是“将东西写入中间文件”是多么伟大和简单可预测且可批处理。

为了更多地帮助设计过程并充实您的需求:

看一小块拼图,做出一些合理的假设,然后跳入解决方案评估是很容易的。但是,在清楚地了解您的约束条件的情况下,从整体上看待问题会更好。我可以建议这个过程吗:

为您当前的架构创建两个图表,物理的和逻辑的。 在物理图上,为每个物理服务器创建框,并绘制每个框之间的物理连接图。 一定要标注每个服务器可用的资源以及每个连接可用的类型和资源。 包括当前设置中未涉及的物理硬件(如果它可能有用的话)。 (如果您有可用的 SAN,但没有使用它,请将它包含在解决方案可能需要的情况下。) 在逻辑图上,为当前架构中运行的每个应用程序 创建框。 将相关库包含在应用程序框中。 (这很重要,因为您未来的解决方案图目前将 PyTables 作为一个盒子,但它只是一个库,不能靠它自己做任何事情。) 将磁盘资源(如 HDF5 和 CSV 文件)绘制为柱面。 根据需要将带有箭头的应用程序连接到其他应用程序和资源。始终将箭头“演员”“目标”。因此,如果应用程序写入 HDF5 文件,它们的箭头会从应用程序指向文件。如果应用读取 CSV 文件,箭头会从应用指向文件。 每个箭头都必须标有通信机制。未标记的箭头显示了一种关系,但它们不显示什么关系,因此它们不会帮助您做出决定或传达约束。

一旦你完成了这些图表,复制它们,然后在它们上面开始做数据流涂鸦。为每个需要原始数据的“终点”应用程序复制一份图表,从模拟开始,并在终点以一个非常实心的流动箭头结束。每当您的数据箭头穿过通信/协议箭头时,请记下数据如何变化(如果有)。

此时,如果您和您的团队都同意纸上的内容,那么您已经以一种应该易于与任何人交流的方式解释了您当前的架构。 (不仅是 *** 上的帮手,还有老板、项目经理和其他钱包持有者。)

要开始规划您的解决方案,请查看您的数据流图并从端点向后工作,并创建一个嵌套列表,其中包含返回起点的每个应用程序和中间格式。然后,列出每个应用程序的要求。一定要推荐:

此应用程序可以使用哪些数据格式或方法进行通信。 它实际需要什么数据。 (这总是一样的还是会根据其他要求随心所欲地改变?) 多久需要一次。 应用程序大约需要多少资源。 应用程序做得不好,现在做什么。 这个应用程序现在可以做什么会有所帮助,但它没有做。

如果您在此列表中做得很好,您会看到这将如何帮助您定义您选择的协议和解决方案。您查看数据通过通信线路的情况,并比较通信双方的需求列表。

您已经描述了一种特殊情况,即您有相当多的 Java 后处理代码对 CSV 文件中的数据表进行“连接”,这是“现在做,但做得不好” .所以你看看沟通的另一方,看看对方是否能做好这件事。此时,另一边是 CSV 文件,在此之前是模拟,所以不,在当前架构中没有什么比这更好了。

因此,您提出了一个新的 Python 应用程序,该应用程序使用 PyTables 库来改进该过程。到目前为止听起来不错!但是在您的下一个图表中,您添加了一堆与“PyTables”对话的其他内容。现在我们已经扩展了对 *** 小组的理解,因为我们不知道其他应用程序的需求。但是,如果您像上面提到的那样制作要求列表,您就会确切地知道要考虑什么。也许您使用 PyTables 提供对 HDF5 文件的查询的 Python 应用程序可以支持所有这些应用程序。也许它只会支持其中的一两个。也许它会为后处理器提供实时查询,但会定期为其他应用程序编写中间文件。我们无法判断,但通过计划,您可以。

一些最终指南:

保持简单!这里的敌人是复杂性。您的解决方案越复杂,实施该解决方案的难度就越大,失败的可能性就越大。使用最少数量的操作,使用最简单的操作。有时,只有一个应用程序来处理架构中所有其他部分的查询是最简单的。有时,处理“实时”查询的应用程序和处理“批量请求”的单独应用程序会更好。 保持简单!这很重要!不要写任何已经可以为你完成的东西。 (这就是为什么中间文件可以这么大,操作系统处理所有困难的部分。)另外,你提到关系数据库的开销太大,但考虑到关系数据库还带有一个非常有表现力和众所周知的查询语言,与之配套的网络通信协议,并且您无需开发任何东西即可使用它!无论您想出什么解决方案,都必须比使用现成的解决方案更好,这肯定是非常有效的,否则它就不是最好的解决方案。 经常参考您的物理层文档,以便了解您考虑的资源使用情况。缓慢的网络链接或在一台服务器上放置过多都可以排除其他好的解决方案。 保存这些文档。 无论您做出什么决定,您在此过程中生成的文档都是有价值的。将它们 Wiki 或归档,以便在话题出现时再次将它们抽出来。

以及直接问题的答案,“如何让 Python 和 Java 协同工作?”只是“使用与语言无关的交流方法”。事情的真相是 Python 和 Java 对你描述的问题集都不重要。重要的是流经它的数据。任何可以轻松有效地共享数据的东西都会很好。

【讨论】:

同意。在不了解 PyTables 层需要做什么的情况下,很难知道提问者需要什么。一些用例会有所帮助。 +1 表示我见过的最完整、最全面的回复。你当然是对的,我应该想办法将系统彼此分离并编程为与程序无关的接口,以便以后可以更轻松地修改。我为不稳定的图表道歉;我是新手,之前没有制作太多图表/图表来说明复杂系统的组件。我一定会听取您的建议,修改架构图,并将我的结果发布在这里,以便其他人也可以受益。【参考方案2】:

不要让它变得过于复杂。

您的 Java 进程可以——简单地——生成一个单独的子进程来运行你的 PyTables 查询。让操作系统做操作系统最擅长的事情。

您的 Java 应用程序可以简单地 fork 一个具有必要参数作为命令行选项的进程。然后,当 Python 在后台运行时,您的 Java 就可以继续进行下一件事情了。

这在并发性能方面具有巨大的优势。您的 Python“后端”与 Java 模拟“前端”同时运行。

【讨论】:

【参考方案3】:

您可以尝试Jython,这是一个用于 JVM 的 Python 解释器,它可以 import Java 类。

Jython project homepage

不幸的是,这就是我所知道的关于这个主题的全部内容。

【讨论】:

PyTables 需要 NumPy,AFAIK 不适用于 Jython。不过,他可能可以从 Jython 访问他的 Java HDF5 库。【参考方案4】:

不确定这是否是好的礼仪。我无法将我所有的 cmets 放入正常的评论中,并且该帖子已 8 个月没有活动。

只是想看看你的情况如何?我们在我工作的地方有一个非常非常相似的情况——只有模拟是用 C 语言编写的,存储格式是二进制文件。每次老板想要不同的总结时,我们都必须制作/修改手写代码来做总结。我们的二进制文件大小约为 10 GB,每年都有一个模拟文件,所以你可以想象,当我们想用不同的种子等运行它时,事情会变得很棘手。

我刚刚发现了 pyTables,并且和你的想法相似。我希望将我们的存储格式更改为 hdf5,然后使用 pytables 运行我们的摘要报告/查询。其中一部分涉及加入每年的表格。使用 pytables 进行这些类型的“连接”是否很幸运?

【讨论】:

实际上,在有机会实施这篇文章中的任何想法之前,我已经转向了一个不同的项目。这就是生活。我认为团队中的其他人并没有提出使用 PyTables 的想法。我觉得还是值得的。

以上是关于Python、PyTables、Java - 捆绑在一起的主要内容,如果未能解决你的问题,请参考以下文章

PyTables 之外的 CArray 和 EArray 兼容性

Python pandas 'HDFStore requires PyTables' Issue

python3.5 ImportError HDFStore需要PyTables没有名为表的模块[重复]

python 来自http://www.pytables.org/usersguide/introduction.html

使用python(numpy memmap,pytables或其他?)对巨大矩阵进行快速下采样

pytables 的 DLL 加载失败