2010-12-08 120 views
2

我想在Java中开发一段代码,它将能够处理JDBC驱动程序从SQL数据库中获取的大量数据,然后将其保留回数据库。一个阅读器线程,一个写入器线程,n个工作线程

我想创建一个包含一个读取器线程,一个写入器线程和可定制数量的工作线程处理数据的管理器。阅读器线程会将数据读取到DTO,并将它们传递给Queue标签“准备处理”。工作者线程将处理DTO并将处理后的对象放置到另一个标记为“准备好持久化”的队列中。编写器线程会将数据保存到数据库。这种方法是最佳的吗?或者,也许我应该让更多的读者获取数据? Java中是否有任何准备好的库用于执行这种我不知道的事情?

回答

3

您提出的方法是否最优取决于处理数据的成本与从数据库获取数据的成本有多大以及如何将结果写回数据库中。如果处理相对昂贵,这可能会工作得很好;如果不是这样,那么可能会带来相当多的复杂性,但效果不大(您仍然会得到管道并行性,这对于整体吞吐量可能并不重要)。

要确保的唯一方法是基准三个阶段分开,然后依赖于最优设计。

如果多线程方法行之有效,那么带有两个队列的设计听起来很合理。您可能需要考虑的另一件事是对每个队列的大小进行限制。

1

使用显式队列的替代方法是使用ExecutorService并向其中添加任务。这样你可以让Java管理器成为线程池。

1

您正在描述写类似于Spring Batch提供的功能的东西。如果我是你,我会检查一下。我有很大的运气来做类似于你所描述的操作。并行和多线程处理,以及几个不同的数据库读者/作者和其他一些东西提供。

2

我听到了过去的回声,我想提供一种不同的方法,以防万一您要重复我的错误。它可能会或可能不适用于您的情况。

您写道,您需要从数据库中提取大量数据,然后保留回数据库。

是否可以将需要使用的外部数据临时插入到数据库中,并执行数据库内的所有处理?这将具有以下优点:

  1. 它消除了需要提取大量数据
  2. 它消除了需要持续大量的数据
  3. 它使基于集合的处理(其性能优于程序)的
  4. 如果您的数据库支持它,您可以使用并行执行
  5. 它为您提供了一个框架(表和SQL)来报告您在过程中遇到的任何错误。

举个例子。很久以前,我实施了一个(java)程序,其目的是将文件中的购买,付款和相关客户数据加载到中央数据库中。那时(我对此深感遗憾),我设计了负载以逐个处理事务,并为每个数据执行多个数据库查找(sql),最后还有一些插入到适当的表中。当然,这个数量一旦增加就不会缩放。

然后我又犯了一个错误。我认为这是数据库问题(因为我有听说 SELECT慢),所以我决定从数据库中提取所有数据,并在Java中进行所有处理。然后最后将所有数据保存到数据库。我用回调机制实现了各种各样的层,以轻松扩展加载过程,但我无法让它表现良好。

从后视镜看,我应该做的是在表格中临时插入(可笑的少量)100,000行,并从那里处理它们。如果我发挥我掌握的所有技术的优势,花费将近半天的时间处理最多花费几分钟的时间。

1

使用Spring批处理!那正是你需要的