使用 JDBC 设置高 maxPoolSize 时需要注意哪些风险/因素
What are the risks / factors to watch when setting a high maxPoolSize with JDBC
我的应用程序是一个 Piwik Server,它从放置在数百个网站上的跟踪代码接收传入的跟踪数据。随着这些跟踪请求的到来,大部分工作负载是每秒数百次对数据库的小写操作。我正在使用 MySQL 服务器和 JDBC 和 Hibernate。
我最近一直在逐渐增加我的应用程序的 maxPoolSize 设置以提高性能。确实好像我设置的配置越高,应用程序响应越快,磁盘队列深度越稳定。
我目前的配置:
jdbc.maxPoolSize=100
jdbc.minPoolSize=100
jdbc.maxStatements=1000
本质上,我的问题是增加 maxPoolSize 时应该注意哪些风险?是否有任何我应该注意的特定因素或指标来判断我是否将此设置配置得太高?显然,如果增加 maxPoolSize 是解决性能问题的灵丹妙药,那么每个人都会希望将其设置得尽可能高。如果这是重复的,请提前致歉,但我找不到任何解决如何评估连接池是否太大.
的答案
我在 AWS RDS 实例上 运行 MySQL。这些是我对问题可能是什么的猜测:
避免超过RDS实例类型允许的最大连接数
过高的设置是否会耗尽服务器上的所有内存并影响性能?
太多线程是否会导致表锁定并增加某些查询的排队时间?
如能协助理解需要注意的因素,我们将不胜感激。
Avoid exceeding the maximum number of connections allowed by the RDS instance type.
这是有道理的。
Would an excessively high setting suck up all the memory on the server and impact performance?
这是可能的。池中的每个活动连接都将具有关联的缓冲区等。但是我希望缓冲区是有界的。
Will too many threads cause tables to lock and increase queue time for some of the queries?
可能吧。但是,如果您主要进行小型写入,那么我不会认为锁定会成为其他写入的一个问题。但是,如果您正在执行需要 table 扫描的同时查询,锁定可能是一个问题。
但是,我没想到增加池大小(超过 100)可能会增加吞吐量。检查数据库实例上的 CPU and/or 磁盘 I/O 负载,或前端与数据库实例之间的网络流量。如果数据库是瓶颈所在,那么让前端同时发出更多的请求很可能会使性能变差。
您需要考虑如果系统上的负载(例如请求率)超过它可以承受的总吞吐量会发生什么情况。如果池大小太大,则前端负载峰值可能会变成数据库负载峰值,从而导致吞吐量 下降 。问题是您不知道什么时候会出现负载峰值,除非您事先负载测试您的系统并调整了池大小,否则您不会知道什么池大小变化的(实际)影响将是...
我强烈建议设置 DropWizard metrics and/or JMX monitoring。
在 JMX 的情况下,绘制 "Active Connections" 随着时间的推移,如果您的池从未超过(或很少超过)给定阈值,则将 maximumPoolSize 设置为高于该阈值只会浪费资源。
在 DropWizard 指标的情况下,"Usage" 测量值 -- 反映连接离开池的时间长度 -- 会给出一个 "comparable" 供您在使用 最大池大小.
如果当 maximumPoolSize 为 50
(例如)与 40
相比时,连接离开池的时间更长,这表明数据库过饱和,40
接近理想状态。
如果 30
的 maximumPoolSize 与 40
相比没有区别(同样,只是一个例子),它 可能意味着40
只是不必要的高,或可能意味着那些收集的指标只是需求低迷时期,40
可能仍然是正确的。
最重要的是将上述指标与 Web 请求服务总时间相结合,并将它们叠加在图表上或至少并排叠加。
指标是分析的关键!尽可能多地查找和跟踪相关信息;模式将会出现。
最后,您可以尝试为 minumumIdle=20
和 maximumPoolSize=100
设置池并查看池 通常 稳定的位置,忽略偶尔的峰值。 RDS 不同于典型的数据库,在典型的数据库中,您可以控制数据库 运行ning 所在的硬件。对于 RDS,您真的不知道 Amazon 是如何分散负载的,所以它只需要进行试验。让每个实验 运行 足够长(几个小时)以收集足够的数据,并截取您的显示器的屏幕截图以进行比较。
我的应用程序是一个 Piwik Server,它从放置在数百个网站上的跟踪代码接收传入的跟踪数据。随着这些跟踪请求的到来,大部分工作负载是每秒数百次对数据库的小写操作。我正在使用 MySQL 服务器和 JDBC 和 Hibernate。
我最近一直在逐渐增加我的应用程序的 maxPoolSize 设置以提高性能。确实好像我设置的配置越高,应用程序响应越快,磁盘队列深度越稳定。
我目前的配置:
jdbc.maxPoolSize=100
jdbc.minPoolSize=100
jdbc.maxStatements=1000
本质上,我的问题是增加 maxPoolSize 时应该注意哪些风险?是否有任何我应该注意的特定因素或指标来判断我是否将此设置配置得太高?显然,如果增加 maxPoolSize 是解决性能问题的灵丹妙药,那么每个人都会希望将其设置得尽可能高。如果这是重复的,请提前致歉,但我找不到任何解决如何评估连接池是否太大.
的答案我在 AWS RDS 实例上 运行 MySQL。这些是我对问题可能是什么的猜测:
避免超过RDS实例类型允许的最大连接数
过高的设置是否会耗尽服务器上的所有内存并影响性能?
太多线程是否会导致表锁定并增加某些查询的排队时间?
如能协助理解需要注意的因素,我们将不胜感激。
Avoid exceeding the maximum number of connections allowed by the RDS instance type.
这是有道理的。
Would an excessively high setting suck up all the memory on the server and impact performance?
这是可能的。池中的每个活动连接都将具有关联的缓冲区等。但是我希望缓冲区是有界的。
Will too many threads cause tables to lock and increase queue time for some of the queries?
可能吧。但是,如果您主要进行小型写入,那么我不会认为锁定会成为其他写入的一个问题。但是,如果您正在执行需要 table 扫描的同时查询,锁定可能是一个问题。
但是,我没想到增加池大小(超过 100)可能会增加吞吐量。检查数据库实例上的 CPU and/or 磁盘 I/O 负载,或前端与数据库实例之间的网络流量。如果数据库是瓶颈所在,那么让前端同时发出更多的请求很可能会使性能变差。
您需要考虑如果系统上的负载(例如请求率)超过它可以承受的总吞吐量会发生什么情况。如果池大小太大,则前端负载峰值可能会变成数据库负载峰值,从而导致吞吐量 下降 。问题是您不知道什么时候会出现负载峰值,除非您事先负载测试您的系统并调整了池大小,否则您不会知道什么池大小变化的(实际)影响将是...
我强烈建议设置 DropWizard metrics and/or JMX monitoring。
在 JMX 的情况下,绘制 "Active Connections" 随着时间的推移,如果您的池从未超过(或很少超过)给定阈值,则将 maximumPoolSize 设置为高于该阈值只会浪费资源。
在 DropWizard 指标的情况下,"Usage" 测量值 -- 反映连接离开池的时间长度 -- 会给出一个 "comparable" 供您在使用 最大池大小.
如果当 maximumPoolSize 为 50
(例如)与 40
相比时,连接离开池的时间更长,这表明数据库过饱和,40
接近理想状态。
如果 30
的 maximumPoolSize 与 40
相比没有区别(同样,只是一个例子),它 可能意味着40
只是不必要的高,或可能意味着那些收集的指标只是需求低迷时期,40
可能仍然是正确的。
最重要的是将上述指标与 Web 请求服务总时间相结合,并将它们叠加在图表上或至少并排叠加。
指标是分析的关键!尽可能多地查找和跟踪相关信息;模式将会出现。
minumumIdle=20
和 maximumPoolSize=100
设置池并查看池 通常 稳定的位置,忽略偶尔的峰值。 RDS 不同于典型的数据库,在典型的数据库中,您可以控制数据库 运行ning 所在的硬件。对于 RDS,您真的不知道 Amazon 是如何分散负载的,所以它只需要进行试验。让每个实验 运行 足够长(几个小时)以收集足够的数据,并截取您的显示器的屏幕截图以进行比较。