4

长话短说:如何让数百个同时运行的进程通过一个或几个永久会话与数据库通信?

整个故事:
我曾经构建了一个数字处理引擎,它通过一个接一个地分叉一个子节点来处理大量的大数据文件,给每个子节点少量的文件来处理。文件锁定、进度监控和结果传播发生在 Oracle 数据库中,所有(子)进程使用封装 DBI 的特定于应用程序的模块在不同时间访问。

起初这很有效,但现在随着输入数据量的增加,不断打开和关闭的数据库会话数量(每个孩子一个,而且它们的寿命可能很短)已成为一个问题。我现在想集中数据库访问,以便只有一个或几个固定数据库会话处理所有(子)进程的所有数据库访问。数据库抽象模块的存在应该使更改变得容易,因为工作实例中的函数调用可以保持不变。我的问题是我想不出一种合适的方法来增强所述模块,以便在所有进程和数据库连接器之间建立通信。

我想到了消息队列,但无法想出一种方法将一大群请求者与一个或几个数据库连接器连接起来,以便可以进行双向通信(用于收集查询结果)。
异步方法在这里可以提供帮助,因为所有请求都写入同一个队列,并且为请求提供服务的数据库连接器将“回调”以提交结果。但是我无法生成足够清晰的图像以便我可以将其绘制成代码。
线程而不是分叉可能让我更容易开始,但这现在需要对代码库进行大量更改,而我不准备对实时系统进行更改。

我想得越多,基本想法对我来说就越像是一个预分叉的 Web 服务器,只是它不提供网页而是提供数据库查询。关于挖掘什么以及在哪里挖掘的任何想法?启发我的示例(伪)代码,可能相关文章的链接,CPAN 上的现成解决方案可能吗?

4

5 回答 5

3

我认为你应该考虑增加一个层次。我认为POE可以处理中间层。

于 2009-05-06T15:46:46.720 回答
1

看看DBD::Gofer。它被设计成一个单独的进程来池和管理数据库连接。

于 2009-05-06T15:43:47.383 回答
1

您可能想与您的 DBA 讨论“共享服务器”,这在 Oracle >= 10 中很容易实现。您可以将其视为服务器端的连接池。因此,当您请求连接时,您不一定要创建一个新的专用服务器进程,并在连接时将其销毁。

您也可以在您身边进行连接池。

于 2010-04-21T21:31:59.637 回答
0

您可能会查看 SQLRELAY,它在代理方面也有一些其他优势。

http://sqlrelay.sourceforge.net/sqlrelay/

于 2009-05-07T11:01:03.203 回答
0

在给定的场景中,最好使用消息队列:

  • 对于工作单元锁定:对锁定/解锁单例的请求进行排队。如果无法获取锁,请重新安排工作单元稍后的时间。
  • 对于进度监控:将所有进度更新放入队列中,由一些记录器/状态更新器等处理。
  • 对于结果提交,将结果集放入队列中,由专门的结果编写者插入。队列条目可能会变得非常大,但任何体面的消息队列都应该能够处理这个问题。在紧要关头,我们可以将有效负载代理到文件中,并且只对文件名和位置进行排队。
  • 配置数据可以在工作进程被分叉之前在启动时从数据库中读取,因此它们在分叉期间继承了完整的配置,并且不需要自己的数据库连接。

当我们这样做时,我们可以重构整个设计以使用一些长寿命的工作守护进程而不是短寿命的分叉,后者也从队列中获取它们的工作单元。这将节省所有分叉的开销。

受企业软件安装限制的限制,当时这种方法不可能实现,但现在从头开始构建类似的东西时,这对我来说是可行的方法。

于 2012-09-11T08:22:10.223 回答