python - pgBouncer 如何帮助加速 Django

标签 python django postgresql connection-pooling pgbouncer

我有一些基于 gevent 的管理命令。由于我的管理命令发出数千个请求,因此我可以使用 Gevent 将所有套接字调用转换为非阻塞调用。这确实加快了我的应用程序,因为我可以同时发出请求。

目前我的应用程序的瓶颈似乎是 Postgres。这似乎是因为用于连接 Django 的 Psycopg 库是用 C 编写的,不支持异步连接。

我还了解到使用 pgBouncer 可以将 Postgres 速度提高 2 倍。这听起来不错,但如果有人能解释 pgBouncer 的工作原理和帮助,那就太好了?

谢谢

最佳答案

除了节省连接和断开连接的开销之外,连接池可以将大量客户端连接汇集到少量实际数据库连接。在 PostgreSQL 中,事件数据库连接的最佳数量通常在 ((2 * core_count) + Effective_spindle_count) 左右。超过这个数字,吞吐量和延迟都会变得更糟。 注意:最近的版本提高了并发性,所以在 2022 年我会推荐类似 ((4 * core_count) + effective_spindle_count) 的东西。

有时人们会说“我要支持 2000 个用户,并且响应时间快”。几乎可以保证,如果您尝试使用 2000 个实际数据库连接来执行此操作,性能将非常糟糕。如果您有一台具有四个四核处理器的机器并且事件数据集已完全缓存,那么通过将请求集中到大约 35 个数据库连接中,您将看到这 2000 个用户的性能要好得多。

要理解为什么这是真的,这个思想实验应该会有所帮助。考虑一个假设的数据库服务器机器,它只有一个资源可以共享——一个内核。该核心将在所有并发请求之间平等地进行时间切片,而不会产生开销。假设有 100 个请求同时进入,每个请求都需要一秒钟的 CPU 时间。核心对所有这些都起作用,在它们之间进行时间切片,直到它们都在 100 秒后完成。现在考虑如果在前面放置一个连接池会发生什么情况,该连接池将接受 100 个客户端连接,但一次只向数据库服务器发出一个请求,将在连接繁忙时到达的所有请求放入队列中。现在当 100 个请求同时到达时,一个客户端在 1 秒内得到响应;另一个在 2 秒内得到响应,最后一个客户端在 100 秒内得到响应。没有人需要等待更长的时间才能得到响应,吞吐量是一样的,但平均延迟是 50.5 秒而不是 100 秒。

一个真正的数据库服务器有更多的资源可以并行使用,但同样的原则也成立,一旦它们饱和,你只会通过添加更多的并发数据库请求来伤害事情。它实际上比示例更糟糕,因为任务越多,任务切换越多,锁和缓存争用增加,L2 和 L3 缓存行争用,以及许多其他会影响吞吐量和延迟的问题。最重要的是,虽然较高的 work_mem 设置可以通过多种方式帮助查询,但该设置是 每个连接的每个计划节点的限制,因此对于较大的您需要保持非常小的连接数以避免刷新缓存甚至导致交换,这会导致计划变慢或哈希表溢出到磁盘之类的事情。

一些数据库产品有效地在服务器中构建了一个连接池,但 PostgreSQL 社区的立场是,由于最好的连接池是在更接近客户端软件的地方完成的,他们将把它留给用户来管理。大多数池化程序将有一些方法将数据库连接限制为一个硬数字,同时允许更多的并发客户端请求,并根据需要对它们进行排队。这就是您想要的,它应该在事务的基础上完成,而不是每个语句或连接。

关于python - pgBouncer 如何帮助加速 Django,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10419665/

相关文章:

python - 为什么切片二维数组的不同方法会给我一组额外的括号?

python - python中与append()函数相反的是什么?

sql - 计算出重叠 er 数据库中的总人数

ruby-on-rails - 如何在 group_by 计数查询中获取总结果集大小?

java - org.postgresql.util.PSQLException : No value specified for parameter 1.-Postgres

Python 3.x 导入错误 SyntaxError

python - 即使通过 webdriver+python 设置浏览器首选项后也无法抑制操作系统下载文件窗口

python -/admin/login/(1698, "Access denied for user ' root'@'localhost'") 出现操作错误

python - Django 使用对象自己的数据对多个更新进行建模?

django - 什么样的 Python 在 Windows 上工作会阻止 mod-wsg/Apache 处理多个请求的能力?