在多个map-reduce作业之间传递DB连接对象

时间:2012-10-29 05:10:04

标签: java database postgresql hadoop mapreduce

从根本上说,这个问题是关于:可以在多个进程中使用相同的数据库连接(因为不同的map-reduce作业在不同的独立进程中)。

我知道这是一个小问题,但如果有人能够回答这个问题会很好:如果与DB的最大连接数(在托管数据库的服务器上预先配置)有什么情况会发生筋疲力尽,新流程试图获得新连接?是否等待某个时间,如果是,是否有办法为此等待期设置超时。在这种特殊情况下,我正在谈论PostGres数据库,而用于与数据库交谈的语言是java。

为了给你一个问题的上下文,我有多个map-reduce作业(大约40个reducers)并行运行,每个都希望更新一个PostGres DB。如何从这些进程有效地管理这些数据库读/写。注意:数据库托管在一台独立的计算机上,与运行map reduce作业的位置无关。

连接池是一种选择,但有时效率非常低,特别是每秒几次读/写。

1 个答案:

答案 0 :(得分:4)

  

可以跨多个进程使用相同的数据库连接

不,没有任何理智或可靠的方式。您可以使用经纪人流程,但无论如何您都要远离发明连接池。

  

如果有最大连接数,会发生什么情况   DB(在托管数据库的服务器上预先配置)已经用尽   并且新进程尝试建立新连接?

SQLSTATE 53300 too_many_connections连接尝试失败。如果它等待,服务器可能会耗尽其他限制并开始为现有客户端提供服务。


对于这样的问题,您通常使用C3P0或DBCP之类的工具进行JVM内部池化,但是当您拥有多个JVM时,这不会起作用。

您需要做的是使用外部连接池(如PgBouncerPgPool-II)来维护工作人员的一组轻量级连接。然后,pooler具有较少数量的真实服务器连接,并在来自客户端的轻量级连接之间共享它们。

连接池通常更多效率高于非池化,因为它允许您优化活动PostgreSQL工作进程的数量到硬件和工作负载,为工作提供接纳控制。

另一种方法是让一个带有一个或多个线程的编写器进程(每个线程一个连接)从reduce worker那里完成工作并写入DB,这样reduce工作者就可以继续下一个工作单元。如果作家太落后,你需要有办法告诉减少工人等待。有几种Java排队系统实现适合于此,或者您可以使用JMS。

请参阅IPC Suggestion for lots of small data

使用以下内容,尽可能优化写入PostgreSQL的方式也值得:

  • 准备好的陈述
  • A commit_delay
  • synchronous_commit = 'off'如果服务器崩溃,您可以承担丢失一些交易的费用
  • 将工作分配到更大的交易中
  • COPY或多值INSERT以插入数据块
  • 使用有用磁盘子系统的硬件,而不是某些带有糟糕I / O的Amazon EC2实例或带有5400rpm磁盘的RAID 5盒
  • 具有电池备份回写高速缓存的适当RAID控制器,以降低fsync()的成本。最重要的是,如果你不能做大批量的工作或使用提交延迟;如果由于批处理和组提交而导致fsync率较低,则影响较小。

请参阅: