Python3.x如何在进程之间共享数据库连接?

use*_*259 6 python mysql multiprocessing python-3.x

我正在使用multiprocessing.Pool运行许多进程

每个进程都要查询我的mysql数据库.

我目前连接到数据库一次,然后共享进程之间的连接

它有效但偶尔会出现奇怪的错误.我已经确认在查询数据库时会导致错误.

我认为问题是因为所有进程都使用相同的连接.

  • 它是否正确?

当我寻找答案时,我偶然发现了这个q&a 如何在Python中的多个进程之间共享一个MySQL数据库连接

所以我查了一下类pooling.MySQLConnectionPool

如果我明白这一点.我将建立一个具有多个连接的池,并在进程之间共享池.然后,每个进程将查看该池,如果连接可用,则使用它,或者等待直到释放连接.

  • 它是否正确?

但后来我发现这个q&a 从Python多处理访问MySQL连接池

似乎首先"mata"证实了我的怀疑但同时他驳回了在进程之间共享设置池的用法

在不同进程之间共享数据库连接(或连接池)将是一个坏主意(我非常怀疑它甚至可以正常工作),

相反,他建议

所以每个进程使用它自己的连接实际上是你应该瞄准的目标.

那是什么意思?

  • 我应该为每个工人创建一个连接吗?那么mysql池有什么用呢?

mata在他的回答中给出的例子似乎足够合理但我不理解整个池作为init参数的传递

p = Pool(initializer=init)
Run Code Online (Sandbox Code Playgroud)
  • 为什么?(正如ph_singer在评论中指出的那样,这不是一个好的解决方案)

将阻塞的Pool.map()方法更改为Pool.map_async()并将池中的连接发送到map_async(q,ConnObj)应该足够了吗?

  • 它是否正确?

在评论中提到了这一点

利用具有许多进程的单个池的唯一方法是使用一个专用进程,该进程使用队列与所有数据库访问进行通信

更新找到了这个.似乎同意:https://stackoverflow.com/a/26072257/1267259

如果您需要大量并发工作者,但他们并不是一直使用数据库,那么您应该拥有一组数据库工作进程来处理所有数据库访问并与您的其他工作进程交换数据.每个数据库工作进程都有一个DB连接.其他进程只通过数据库工作人员与数据库通信.

Python的多处理队列,fifos等为此提供了适当的消息传递功能.

  • 这真的是对的吗?

是不是mysql池的目的是处理进程的请求并将它们转发到可用的连接?

现在我只是困惑......

use*_*259 5

在Python中跨进程发现Share与postgres db的连接
我的第一个问题的答案似乎是

您无法像这样跨进程合理共享数据库连接。您可以排序共享线程之间的连接,但前提是确保一次仅一个线程使用该连接。在进程之间这是行不通的,因为在客户端的地址空间中存储了连接的客户端状态。

剩下的问题的答案基本上可以归结为以下哪些陈述(来自本问答的评论中的讨论)

基本上,这个想法是在主进程中创建一个连接池,然后在每个产生的线程/进程中,从该池请求连接。线程不应共享相同的相同连接,因为线程可以相互阻塞,而线程应该帮助它们进行以下一项主要活动:IO。– F先生

要么

既不传递池,也不传递池与子进程的连接

每个子进程都会根据需要创建自己的数据库连接(单独或作为池)– JF Sebastian。

“为什么使用[db连接]池”-如果您的工作进程中有多个线程,则该池可能很有用(几个线程可以并行读取/写入数据(CPython可以在I / O期间释放GIL))。如果每个工作进程只有一个线程,则没有必要使用数据库池。–塞巴斯蒂安(JF Sebastian)


作为旁注

这不能完全回答我的第三个问题,但实际上确实提出了在某些情况下为每个进程创建连接(在Python中跨进程共享与postgres db的连接

目前尚不清楚您在这里寻找什么。5个连接当然不是问题。您是说您最终可能需要产生100或1000个进程,每个进程都有各自的连接?如果是这样,即使您可以共享它们,它们也将被绑定到连接池,因为在任何给定时间只有一个进程可以使用给定的连接。– khampson 2014年9月27日5:19