【问题标题】:Huge data processing/ HPC in Java - suggest me how to beginJava 中的海量数据处理/HPC - 建议我如何开始
【发布时间】:2012-09-30 16:08:00
【问题描述】:

我正在考虑解决一个编程问题,我想我需要了解很多高级编程概念。由于某些原因,我决定用 Java 编写代码——即使我并不精通它。 因此,我希望您为我提供建议、指导、资源指针、书籍、教程或任何您认为相关的通用建议。

这是我的问题的基本性质:

  1. 我需要创建一个客户端-服务器架构。服务器支持多个并发客户端。客户端向其发送简单指令(可能是服务器公开某种 API/在特定端口上运行监听器),服务器执行指令并将结果发送回客户端。

  2. 服务器的主要工作是根据给它的指令进行大量的数据处理。它从后端数据库/文件系统获取数据。数据量可以轻松飙升至 ~ 200GB - 700GB。数据通常会流式传输到它,但在处理过程中可能需要在内存缓存中保存大量数据(如果 RAM 不够,则将其分页到磁盘)。计算在本质上通常是数值密集型(比如说对矩阵求逆)

  3. 服务器应该能够做多线程(我不知道这个术语在Java中是什么意思,我希望的是,服务器应该能够将工作分配给多个并行子流程。)

  4. 服务器本身应该非常轻量级。我不需要任何 GUI 界面。

  5. 如果我以某种方式对其进行设计,这样我以后可以将其与 Hadoop 等 HPC 框架集成,那就太好了。

如果我必须这样做,我需要学习什么样的编程?顺便说一下,我对OOP有很好的理解,我对数据结构和算法有点熟悉,我知道基本的Java(以前从未用Java做过任何网络或多线程编程,但使用过典型的oop概念,泛型,可比的接口等。)。我主要从事数据库编程,但过去也做过很多 C、C++、C#、Python。

鉴于需求和我的背景,请提出建议,

  1. 我应该如何开始这个项目?构建项目的方法是什么?
  2. 我应该先创建一些基本的 API 定义,然后再开始处理细节吗?
  3. 我应该遵循任何特定的设计模式吗?从哪里学习?
  4. 我需要在 Java 中学习哪些内容以及从哪里学习这些内容?
  5. 在内存中读取大量数据的最佳方法是什么? Java nio 是好的解决方案吗?
  6. 如果我用大量数据实例化一个类,它会工作吗? (例如,假设我有一个 Vector 类来表示具有数百万个元素的矩阵,并且该类的构造函数读取内存中的大量数据集)。最好的处理方法是什么?

【问题讨论】:

  • 当“大数据”已经以 TB 到 PB 为单位衡量时,700 GB 并不是“巨大”...您为什么不立即开始使用 Hadoop?

标签: java multithreading design-patterns data-mining hpc


【解决方案1】:

您需要定义客户端和服务器如何相互通信。最简单的方法是使用已建立的协议,例如 HTTP,通过创建客户端无需太多编码即可调用的 REST 服务。

大多数支持 HTTP 的框架都会创建多个在不同线程中运行的侦听器。这为您提供了开箱即用的多线程。

我建议调查一下我更喜欢 Spring 控制器。弹簧的重量相当轻。

如果您想使用这些框架,您会希望快速找到它们,并将它们合并到您的应用程序中进行编译和打包。

我建议为此研究 Maven。这是一个很大的节省时间。特别是使用原型来创建项目的文件夹结构,并自动下载依赖项及其依赖项。

最后是我的智慧之言。确保您的服务是单例无状态服务。这意味着您只创建一次对象,并且每个线程使用相同的对象。发生的垃圾收集要少得多。这在处理大量请求时会产生巨大的差异。

注意不要在这些服务中使用类级别的变量来保存状态。如果这样做,不同的线程将覆盖彼此的数据。

【讨论】:

  • 好的,注意了。用于客户端-服务器架构的 Spring 框架。用于构建过程的 Maven。大容量数据处理呢?多线程计算?
  • 另外,可能是一个愚蠢的菜鸟问题,如果类级别的变量不保存状态,那么我在哪里存储状态?
  • 通常你的服务不应该保持状态。因此,典型 Spring 应用程序中的数据流就像 Spring 控制器以 GETPOST(或其他)请求的形式接收数据一样。所有其他类型的请求都由Controller 类中的某个方法处理。该方法使用 url 映射绑定到一个 url,请求参数使用基于注释的绑定绑定到方法参数。服务执行任务所需的数据应传递给旨在接受该参数的适当服务方法。
  • 另外,如果您需要在当前请求之外持久化数据,您可以将其存储在数据库中。
  • 每个http请求都会在不同的线程中处理。如果您需要进一步分解处理,java 本机允许您在不同的线程中执行一个类。抱歉,我没有示例,正在使用手机工作。
【解决方案2】:

首先我想说的是,根据您对事物的解释,您似乎可以很好地使用 java 作为服务器端语言。

您选择的客户端服务器架构类型可能取决于您实际服务的客户端类型。它们是典型的基于 GUI 或 CUI 的桌面客户端还是 Web 客户端。

在后一种情况下,您可以以正常方式使用 Spring Framework,而对于前一种情况,您可以进一步探索 Spring 对 Restful Web 服务的支持。我建议不要使用基于套接字或 TCP 的网络解决方案或使用 java 网络。

Spring 的RESTful API 为您提供了对网络和多线程等事物的非常酷的抽象,即使对于基于桌面的客户端也是如此。对于桌面客户端,您可以使用 JSON/XML 作为响应,并且可以使用 HttpClient 库来调用服务器,这是对底层网络内容的非常酷的抽象。

进一步说明 Spring 的设计模式遵循非常 linear 的数据流。 Spring 本身使用 Dependency InjectionInversion of Control 满足了您的许多基本设计考虑,它们非常易于合并。

对于与特定需求相关的设计模式的详细分析,我建议您阅读Addison Wesley 出版物中名为Java Design Patterns: A Tutorial 的书,作者是James W. Cooper

关于 API 设计的另一件事。您最好先创建一个 API 规范,然后再进一步实施。

【讨论】:

  • 目前,我假设客户端只是一个 CUI 客户端,它通过 TCP/IP 向服务器发送某种结构化请求。根据您的解释(以及来自@tinman),Spring 似乎符合要求。现在下一个大问题是关于在多线程环境中读取、保存和执行大量数据的复杂计算。有什么建议吗?
  • 我不是一个典型的数据库专家,对此没有太多评论。但我读过,为了处理大量数据,您通常可以求助于 NoSql 系统,其中之一可能是 MongoDB 并使用 caching 来加快处理速度如果您的要求是在给定时间实例处理大量请求,那么 clustering 将是需要注意的事情。结合 cachingclustering 可以让您寻找一种叫做 Distributed Caching 的东西。但我可以把这些当作行话来谈论,你必须做你的研究来探索这些是否值得。
  • 也许考虑购买一本游戏编程书籍,并通过一些多线程 AI 逻辑教程。通过理解游戏,我为企业环境带来了一些技巧。
猜你喜欢
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
相关资源
最近更新 更多