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

问题描述 投票:4回答:5

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

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

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

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

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

database perl dbi
5个回答
3
投票

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


1
投票

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

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


1
投票

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


0
投票

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

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

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

受到企业软件安装限制的约束会让这种方法在当时变得不可能,但是当从头开始构建类似的东西时,这将是我的选择。


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.