【发布时间】:2021-12-31 04:35:19
【问题描述】:
我的 python 应用程序使用 concurrent.futures.ProcessPoolExecutor 和 5 个工作人员,每个进程进行多个数据库查询。
选择为每个进程提供自己的数据库客户端,还是让所有进程共享一个客户端,这被认为更安全和传统?
【问题讨论】:
标签: python python-3.x concurrent.futures
我的 python 应用程序使用 concurrent.futures.ProcessPoolExecutor 和 5 个工作人员,每个进程进行多个数据库查询。
选择为每个进程提供自己的数据库客户端,还是让所有进程共享一个客户端,这被认为更安全和传统?
【问题讨论】:
标签: python python-3.x concurrent.futures
简答:为每个进程(需要它)提供自己的数据库客户端。
长答案:你想解决什么问题?
在进程之间共享数据库客户端基本上不会发生;您必须拥有一个进程,它确实让数据库客户端代理来自其他人的查询,使用或多或少自己的协议。如果该协议特定于您的应用程序,这可能会带来好处,但它会增加复杂性:您的程序中现在将有两种不同类型的工作程序,而不仅仅是一种,加上它们之间的协议。您需要确保好处大于额外的复杂性。
通常可以在线程之间共享数据库客户端;您必须查看文档以查看哪些对象和操作是“线程安全的”。但是,由于您的应用程序在其他方面占用大量 CPU,因此由于 Python 限制(GIL),线程不适合。
同时,在每个进程中拥有一个 DB 客户端的成本很低;在任何情况下,您都需要一些类型的客户,它也可能是直接客户。
不会有更多的 IO,因为这主要基于查询的总数和数据量,无论是来自一个进程还是分散在多个进程中。唯一的额外 IO 将在登录中,这并不多。
如果您的数据库连接不足,您可以调整/升级您的数据库以获得更多连接,或者使用单独的现成“连接池”来共享它们;这可能比尝试从头开始实现连接池要好得多。
更一般地说,这远远超出了这个特定的问题,通常最好以直接的方式组合几个现成的部分,而不是尝试将一个定制的复杂部分组合在一起来完成所有事情一次。
那么,你想解决什么问题?
【讨论】:
最好使用多线程或异步方法而不是多处理,因为它会消耗更少的资源。这样你就可以使用单个数据库连接,但我建议为每个工作程序或协程创建一个单独的会话,以避免一些异常或锁定问题。
【讨论】: