Mysql连接器在com.mysql.jdbc.util.ReadAheadInputStream.fill()中花费50%的时间

时间:2014-08-18 04:14:34

标签: java mysql hibernate jdbc

我正在分析使用Spring,Hibernate和mysql-java-connector的应用程序。 VisualVM显示,当有1000个并行连接正在读取时,com.myql.jdbc.utils.ReadAheadInputStream.fill()方法花费了超过50%的CPU时间。

是否有任何优化可以加快速度?

3 个答案:

答案 0 :(得分:3)

只要JVM认为它可以运行,VisualVM就会将一个线程计为使用CPU时间。这意味着任何不等待锁的线程都被认为是可运行的,或多或少,包括在内核中等待I / O的线程!这是com.myql.jdbc.utils.ReadAheadInputStream.fill()中大量CPU使用率的来源。因此,不存在CPU问题,而是存在I / O问题。

你可以在JVM方面做一些事情,但不是很简单的优化:

  1. 调整连接池大小。 1,000个并发查询是批次。除非你的MySQL实例非常庞大,否则它将无法处理这种负载水平,并且只需在查询之间切换就会耗费大量时间。尝试将池大小降低到250甚至50,并在那里进行基准测试。
  2. 执行更少或更小的查询。如果你的应用很小,很明显每个查询的每一行都是必要的,但也许你的应用程序比那个更大。是不同的地方查询相同的数据,还是可以将两个不同的查询组合成一个满足两者的?

答案 1 :(得分:2)

除了其他建议之外,还要考虑尝试更少量的连接(即20)。 处理如此大量的开放连接的开销很可能会略微愚弄您的分析观察结果。

尤其是,请确保您使用的是最新版本的Hibernate ORM。 我们使5.0+版本比以前的版本更加智能,特别是在性能改进方面;-)每天都会进行改进,因此保持最新状态或至少尝试最新版本可能很容易获胜。

答案 2 :(得分:0)

如果没有其他信息,很难回答您的问题。这里需要满足一些信息需求。

  1. 是您对CPU时间绝对值还是相对值的估计?如果fill()方法使用系统可用的CPU时间的一半,那么这似乎很奇怪。但是如果这个数字是使用VisualVM报告使用时间相对于应用程序花费的时间,那么它可能是你的应用程序的其余部分没有做大量的工作?
  2. 使用系统级工具确认这些分析测量?如果你在Linux上,可以使用pidstatmpstatsar进行交叉检查。我已经看到VisualVM将SocketInputStream.socketRead0()方法花费的时间标记为CPU时间,pidstat未对此进行确认。我想这是VisualVM本身或JVM行为中某些测量近似的结果。所以使用OS工具进行交叉检查总是好主意。