Python, PyTables, Java - 将所有内容捆绑在一起问题简述更详细的解释

2022-09-01 19:26:07

问题简述

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

更详细的解释

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

Current system architecture

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

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

问题

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

溶液?

我的小组认为我们真的需要一种方法来过滤和查询我们拥有的数据,以及执行跨表联接。鉴于这是一次写入,多次读取的情况,我们真的不需要真正的关系数据库的开销;相反,我们只需要一些方法来在HDF5文件上放置一个更好的前端。我找到了一些关于这个问题的论文,例如一篇描述如何使用[XQuery作为HDF5文件的查询语言][3]的论文,但该论文描述了必须编写一个编译器才能从XQuery / XPath转换为本机HDF5调用,这远远超出了我们的需求。输入 [PyTables][4]。它似乎完全符合我们的需要(提供了两种不同的数据查询方式,要么通过Python列表理解,要么通过[内核内(C级)搜索][5]。

我设想的架构是这样的:Envisioned architecture

我不太确定该怎么做的是将编写用于查询的python代码与提供HDF5文件的Java代码以及执行数据后处理的Java代码链接在一起。显然,我想要重写大部分隐式执行查询的后处理代码,而是让优秀的PyTables更优雅地做到这一点。

Java/Python options

一个简单的谷歌搜索发现了一些[在Java和Python之间进行通信][7]的选项,但我对这个话题很陌生,所以我正在寻找一些实际的专业知识和对拟议架构的批评。看起来Python进程应该与Datahose在同一台计算机上运行,这样大型.h5文件就不必通过网络传输,而是将其更小的过滤视图传输到客户端。[火焰兵][8]似乎是一个有趣的选择 - 有人有这方面的经验吗?

答案 1

这是一个史诗般的问题,有很多考虑因素。由于您没有提到任何特定的性能或体系结构约束,因此我将尝试提供最佳全面的建议。

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

这种“我们确切地知道我们的输入和输出,可以只做处理”(批处理)和“我们知道我们的输入以及需要什么来问其他东西”(实时)之间的区别,使架构问题变得完全不同。查看您的关系图,有几个关系暗示着不同的处理方式。

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

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

要直接回答您的问题:

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

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

很容易看到拼图的一小部分,做出一些合理的假设,然后跳入解决方案评估。但是,最好从整体上看待问题,并清楚地了解您的约束。我是否可以建议这个过程:

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

完成这些图表后,制作它们的几个副本,然后在它们之上开始进行数据流涂鸦。使用需要原始数据的每个“端点”应用程序的图表副本,从模拟开始,以几乎实心的流动箭头结束终点。每当数据箭头流经通信/协议箭头时,请记下数据如何变化(如果有)。

在这一点上,如果你和你的团队都同意纸上的内容,那么你已经以一种应该很容易与任何人交流的方式解释了你当前的架构。(这里不仅仅是堆栈溢出的帮手,还有老板、项目经理和其他钱包持有者。

若要开始规划解决方案,请查看数据流图,从终结点向后工作到起始点,并创建一个嵌套列表,其中包含返回起点时的每个应用和中间格式。然后,列出每个应用程序的要求。确保具有以下功能:

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

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

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

因此,您提出了一个新的Python应用程序,该应用程序使用PyTables库来使该过程更好。到目前为止听起来不错!但是在你的下一个图表中,你添加了一堆与“PyTables”相关的其他内容。现在,我们已经超越了StackOverflow团队的理解,因为我们不知道其他应用程序的要求。但是,如果您像上面提到的列出要求列表,您将确切地知道要考虑什么。也许您的Python应用程序使用PyTables来提供对HDF5文件的查询,可以支持所有这些应用程序。也许它只会支持其中的一两个。也许它会为后处理器提供实时查询,但会定期为其他应用程序写入中间文件。我们无法分辨,但通过规划,您可以。

一些最终准则:

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

而直接问题的答案,“如何让Python和Java一起玩得漂亮?”只是“使用一种与语言无关的沟通方法”。事情的真相是,Python和Java对于你描述的问题集都不重要。重要的是流经它的数据。任何可以轻松有效地共享数据的东西都会很好。


答案 2

不要让这比它需要的更复杂。

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

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

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


推荐