每个http请求与连接池的直接数据库连接 - 有什么区别

时间:2017-06-07 07:06:00

标签: java database postgresql connection-pooling sharding

我们说我正在存储Person(id, country_id, name)的数据。并且让我们说用户刚刚发送了id和country_id,然后我们发回了这个名字。

现在我有一个db和2个webserver,每个webserver保持一个20连接的连接池(例如c3p0)。

这意味着db正在维护40个连接,每个Web服务器维护20个连接。

分析上面的系统,我们可以看到我们使用了连接池,因为人们说"创建数据库连接很昂贵"

这一切都有意义

现在让我说我在country_id上分享表数据,所以现在可能有200分贝,也假设我们的应用现在很流行,我们需要有50个网络服务器。
现在,上面的连接池策略失败,就好像每个Web服务器在池中为每个数据库保留20个连接一样 这意味着每个网络服务器将具有20 * 200 db = 4000连接
每个数据库将有50个Web服务器* 20 = 1000连接。

这听起来并不好,所以我得到了一个问题,为什么要使用连接池,每个网页请求创建1个连接的开销是多少?

所以我运行一个测试,我看到DriverManager.getConnection()在localhost上平均需要20毫秒。

每次请求额外20毫秒不是游戏杀手

问题1:每个网络请求使用1个连接还有其他缺点吗?

问题2:互联网上的人们说"数据库连接很昂贵"。有哪些不同的开支?

PS:我也看到pinterest做同样的https://medium.com/@Pinterest_Engineering/sharding-pinterest-how-we-scaled-our-mysql-fleet-3f341e96ca6f

2 个答案:

答案 0 :(得分:2)

如果您有一个繁忙的网站,并且每个对数据库的请求都会打开并关闭一个连接,那么您就已经死了。

您测量的20ms用于localhost连接。我不认为你的所有50个网络服务器都在localhost ...

除了建立和关闭数据库连接所花费的时间之外,它还使用数据库服务器上的资源。这主要是CPU,但也可能存在对内核数据结构的争用。

此外,如果你允许几千个连接,没有任何东西可以防止所有人同时忙碌,在这种情况下你的数据库服务器将会超载并且没有响应,除非它有几千个内核(甚至那么你' d受到锁争用的限制。)

您的解决方案是pgBouncer等外部连接池。

答案 1 :(得分:2)

除连接创建&连接关闭周期是一项耗时的任务(即成本高昂),还可以进行池化以控制与数据库同时打开的连接数,因为数据库服务器可以处理的并发连接数有限制。当你这样做时,每个请求有一个连接,你就失去了控制权,你的应用程序总是有可能在高峰负载时崩溃。

其次,您将不必要地将Web服务器容量与数据库容量联系起来,目标也是将数据库连接管理视为开发人员关注的问题,而不是基础架构问题。您是否愿意根据他/她的代码控制为开发人员打开生产应用程序的数据库连接?

在传统的单片应用程序服务器(如Weblogic,JBoss,WebSphere等)中,其sys管理员将根据db serer容量创建连接池,并将JNDI名称传递给开发人员以使用。开发人员的工作仅限于使用该JNDI获取连接。

接下来,如果数据库在各种独立应用程序之间共享,那么池化会让您知道您向哪个应用程序提供的内容。有些应用程序可能需要更多数据,有些应用程序可能不那么密集。

传统的资源泄漏问题,即当开发人员忘记干净地关闭他们的连接时,也需要使用池。

总而言之 - 集合背后的想法是让开发人员只关心使用连接并完成工作,而不是担心打开和关闭它。如果连接未在X分钟内使用,则每个配置将返回到池。