java使用JDBC设置高maxPoolSize时,需要注意哪些风险/因素
我的应用程序是一个Piwik Server,它从数百个网站上的跟踪代码接收传入的跟踪数据。当这些跟踪请求传入时,工作负载的大部分是每秒数百次对数据库的小写入。我将MySQL服务器与JDBC和Hibernate一起使用
我最近一直在逐渐增加应用程序的maxPoolSize设置,以提高性能。显然,我设置的配置越高,应用程序的响应速度越快,磁盘队列深度越稳定
我当前的配置:
jdbc.maxPoolSize=100
jdbc.minPoolSize=100
jdbc.maxStatements=1000
本质上,我的问题是,当我增加maxPoolSize时,我应该注意哪些风险?是否有任何具体的因素或指标,我应该看,以判断我是否配置此设置过高?显然,如果增加maxPoolSize是解决性能问题的灵丹妙药,那么每个人都希望将其设置得尽可能高。如果这是重复的,请提前道歉,但我找不到任何解决方法来评估您的连接池是否过大
我正在AWS RDS实例上运行MySQL。以下是我对可能存在的问题的猜测:
避免超过RDS实例类型允许的最大连接数
过高的设置会占用服务器上的所有内存并影响性能吗
线程过多会导致表锁定并增加某些查询的队列时间吗
如果您能帮助您了解需要关注的因素,我们将不胜感激
# 1 楼答案
这是有道理的
这是可能的。池中的每个活动连接都有相关的缓冲区等。然而,我希望缓冲区是有界的
可能吧。然而,如果您主要进行小规模的写操作,那么我不会想到锁定会成为其他写操作的一个问题。但是,如果您同时执行需要扫描表的查询,那么锁定可能是一个问题
但是,我没有想到增加池大小(大于100)可能会增加吞吐量。检查数据库实例上的CPU和/或磁盘I/O负载,或者前端和DB实例之间的网络流量。如果数据库是瓶颈所在,那么允许前端同时发出更多请求可能会降低性能
你需要考虑如果系统上的负载(例如请求率)超过它能承受的总吞吐量,将会发生什么。如果池大小太大,那么前端负载峰值可能会变成数据库负载峰值,从而导致吞吐量下降。问题是你不知道什么时候会发生负载尖峰,除非你事先用调整过的池大小对系统进行了负载测试,否则你不知道池大小变化的(实际)影响是什么# 2 楼答案
我强烈建议设立DropWizard metrics和/或JMX monitoring
在JMX的情况下,如果您的池从未超过(或很少超过)给定的阈值,那么将maximumPoolSize设置为高于该阈值只会浪费资源,那么请绘制随时间变化的“活动连接”图
在DropWizard度量的情况下,反映连接离开池多长时间的“使用率”度量将为您在使用maximumPoolSize时提供一个“可比较”的值,供您检查
如果当maximumPoolSize为
50
(例如)而不是40
时,连接离开池的时间较长,则表明数据库已过饱和,40
更接近理想状态如果
30
的最大工具大小与40
之间没有差异(同样,只是一个例子),那么可能意味着40
的值太高了,或这可能意味着收集这些指标的时间段仅仅是一个需求量较低的时间段,并且40
可能仍然是正确的最好的方法是将上述指标与web请求服务总时间结合起来,并将它们叠加在一个图上,或者至少并排叠加
指标是分析的关键!找到并跟踪尽可能多的相关信息;模式将会出现。 最后,您可以尝试将池设置为
minumumIdle=20
和maximumPoolSize=100
,并查看池通常的位置,忽略偶尔的峰值。RDS不同于典型的数据库,您可以控制数据库运行的硬件。有了RDS,你真的不知道Amazon是如何分散负载的,所以这只是需要实验。让每个实验运行足够长的时间(几个小时)以收集足够的数据,并拍摄显示器的屏幕截图进行比较