我正在使用multiprocessing.Pool
运行许多进程每个进程都必须查询我的mysql数据库。
我目前连接数据库一次,然后共享进程之间的连接
它有效但偶尔会出现奇怪的错误。我已经确认在查询数据库时会导致错误。
我认为问题是因为所有进程都使用了相同的连接。
当我寻找答案时,我偶然发现了这个q& a How to share a single MySQL database connection between multiple processes in Python
所以我查了一下Class pooling.MySQLConnectionPool
如果我理解这一点。我将建立一个具有多个连接的池,并在进程之间共享池。然后,每个进程将查看该池,如果有可用的连接,则使用它,否则等待连接被释放。
但后来我发现了这个q& a Accessing a MySQL connection pool from Python multiprocessing
首先,“mata”确认我怀疑的内容,但同时他驳回了在进程之间共享设置池的使用
在不同进程之间共享数据库连接(或连接池)将是一个坏主意(我非常怀疑它甚至可以正常工作),
相反,他建议
所以使用它自己的连接的每个进程实际上都是你应该瞄准的目标。
这是什么意思?
mata在他的回答中给出的例子似乎足够合理,但我不理解整个池作为init参数的传递
p = Pool(initializer=init)
将阻塞的Pool.map()方法更改为Pool.map_async()并将池中的连接发送到map_async(q,ConnObj)应该足够了吗?
在评论中提到了
利用具有多个进程的单个池的唯一方法是使用一个专用进程,使所有数据库访问使用队列与其进行通信
UPDATE发现了这一点。似乎同意:https://stackoverflow.com/a/26072257/1267259
如果您需要大量并发工作者,但他们并不是一直使用数据库,那么您应该拥有一组数据库工作进程来处理所有数据库访问并与您的其他工作进程交换数据。每个数据库工作进程都有一个DB连接。其他进程只通过数据库工作人员与数据库通信。
Python的多处理队列,fifos等为此提供了适当的消息传递功能。
mysql池的目的不是处理进程请求并将它们转发到可用连接吗?
现在我只是困惑......
答案 0 :(得分:4)
找到Share connection to postgres db across processes in Python
我的第一个问题的答案似乎是
您不能在这样的流程之间共享数据库连接。您可以在线程之间共享连接,但前提是您确保连接一次仅由一个线程使用。这不会在进程之间工作,因为存储在客户端地址空间中的连接的客户端状态。
我剩下的问题的答案基本上归结为您接下来的哪些陈述(来自本q& a中的评论中的讨论)
基本上,我们的想法是在主进程中创建连接池,然后在每个生成的线程/进程中,请求来自该池的连接。线程不应该共享相同的相同连接,因为线程可以互相阻塞线程应该帮助的主要活动之一:IO。 - F先生
或
既不传递池,也不传递池中的连接到子进程
每个子进程在需要时创建自己的数据库连接(单独或作为池) - J.F.Sebastian。
和
"为什么要使用[db connections] pool" - 如果您的工作进程中有多个线程,那么该池可能很有用(多个线程可以并行读/写数据(CPython可以在I / O期间释放GIL))。如果每个工作进程只有一个线程,则没有必要使用数据库池。 - J.F. Sebastian
作为旁注
这并没有完全回答我的第三个问题,但它实际上确实在某些情况下为每个流程创建了一个连接(Share connection to postgres db across processes in Python)
目前还不清楚你在这里寻找什么。 5个连接肯定不是问题。你是说你最终可能需要产生100或1000个进程,每个进程都有自己的连接?如果是这样,即使您可以共享它们,它们也会绑定到连接池,因为在任何给定时间只有一个进程可以使用给定的连接。 - khampson Sep 27' 14 at 5:19