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

时间:2009-05-06 15:13:43

标签: database perl dbi

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

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

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

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

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

5 个答案:

答案 0 :(得分:3)

我认为您应该考虑添加一个等级。我认为POE可以处理中间层。

答案 1 :(得分:1)

看看DBD::Gofer。它旨在成为一个独立的流程来集中和管理数据库连接。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

在给定方案中,最好使用消息队列:

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

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

受到企业软件安装限制的约束会使这种方法在当时无法实现,但是当从头开始构建类似的东西时,这将是我的选择。