【问题标题】:How to tune performance of hsqldb/hibernate app如何调整 hsqldb/hibernate 应用程序的性能
【发布时间】:2010-10-21 17:17:28
【问题描述】:

我有一个使用 Hibernate 和 HSQLDB 实现持久性的开源 Java 应用程序。在我所有的玩具测试中,一切都运行得很快,一切都很好。我有一个客户连续运行了几个月的软件,他们的数据库在那段时间里有了很大的增长,性能也逐渐下降。我终于想到数据库可能是问题所在。据我从日志语句中可以看出,服务器中的所有计算都发生得很快,所以这与数据库可能有问题的假设是一致的。

我知道如何对程序进行常规分析,以找出热点在哪里以及什么占用了大量时间。但是我所知道的所有分析器都会监控程序中的执行时间,并且不会为您提供有关调用外部资源的任何帮助。人们使用哪些工具来分析使用外部数据库调用的程序以找出优化性能的地方?

稍微盲目搜索已经发现了一些热点——我注意到一个调用,我正在枚举特定类的所有对象以找出是否有任何对象。对标准 [.setMaxResults(1)] 的一行更改将调用从半秒更改为几乎瞬时。我还看到我在单个事务中多次从数据库中提出相同问题的地方。我还没有想出如何缓存答案,但我真正想要的是一个工具来帮助我更系统地寻找这些东西。

【问题讨论】:

    标签: java hibernate profiling hsqldb


    【解决方案1】:

    在 Terracotta 3.1 中,您可以使用 Terracotta 开发者控制台实时监控所有这些统计数据。您可以查看缓存统计信息的历史图表,并查看集群范围内或每个节点的休眠统计信息或缓存统计信息。

    Terracotta 是开源的。更多详情和下载地址为Terracotta for Hibernate

    【讨论】:

      【解决方案2】:

      这里有很多报道。我有一些结果,并且仍在寻找好的答案。

      我找到了一些有用的工具:

      VisualVM(带有BTrace,或内置 Trace)声称有助于跟踪,但我找不到任何显示方法调用时间的工具。

      YourKit 被认为是有用的;我已经申请了开源许可证。

      我发现最有用的是 Hibernate 的内置统计信息。如果你设置 hibernate.generate_statistics true 在您的属性中,您可以发送sessionFactory.getStatistics(),并查看有关已存储和检索的对象以及缓存的影响的详细统计信息。我在 qeuryStatistics 中找到了我想要的答案之一,它报告了每个编译的查询、缓存命中和未命中、查询运行的次数、返回的行数以及平均、最大和最小执行时间。这些时间安排清楚地表明了时间的去向。

      然后我做了一些关于缓存的阅读。 Razenha的建议是正确的。 [我现在将他的答案标记为正确。] 我将hibernate.cache.use_query_cache true 添加到我的属性中,并将query.setCacheable(true); 添加到我的大多数查询中。我还在一些 .hbm.xml 文件中添加了<cache usage="read-write"/>。现在,我的大部分统计数据都显示缓存命中占主导地位,而且性能要好得多。

      我仍然想要一些工具来帮助我跟踪执行时间,这样我就可以解决最严重的问题,而不是最明显的问题,但这是一个很大的帮助。也许上面的跟踪工具之一会有所帮助。

      【讨论】:

      • yourkit 实用且易于使用。
      【解决方案3】:

      曾经有一个名为 IronGrid/IronEye/IronTrackSql 的工具可以满足您的需求。不幸的是,他们倒闭了。他们确实在最后一刻开源了他们的产品,但我已经有一段时间找不到源代码或二进制文件了。

      我最近一直在使用YourKit 进行分析,部分原因是您可以使用它分析 SQL 时间以查找调用次数最多的语句和运行时间最长的语句。它不像 IronGrid 那样详细,但它确实为您提供了有价值的信息。在我最新的数据库/休眠调整会话中,问题原来是休眠以及它如何以及何时进行急切与延迟加载,并在选择大量项目时添加一些明智的默认覆盖。

      【讨论】:

        【解决方案4】:

        您在 HSQLDB 中存储了多少数据?我认为它在管理大量数据时表现不佳,因为它只是将所有内容存储在文件中......

        【讨论】:

        • 与 hsqldb 相比,我认为它并没有那么大。 .script 文件几乎有 300K 行(32891015 个字符)。我之前看过,数据库中存储了 3000 个市场和 15 万笔交易。所有对象的总行数可能为 250K。
        【解决方案5】:

        不幸的是,据我所知,没有工具可以做到这一点。

        但有些事情您可能需要检查:

        • 您是否使用预先加载而不是延迟加载?根据您的问题描述,您确实没有使用延迟加载...
        • 您是否打开并正确配置了二级缓存?包括查询缓存? Hibernate 缓存机制非常强大和灵活。
        • 您是否考虑过使用 Hibernate Search?根据您的查询,Apache Lucene 之上的 Hibernate Search Full Text 索引可以加快您的查询速度(因为它的索引系统非常强大)

        【讨论】:

        • 我还没有对数据库配置进行任何性能调整。我曾假设我的问题更有可能是构思不当的查询或错误的问题问了太多次。我想我想先找到一种方法来减少查询的数量及其费用,然后(在将使用量减少 80% 之后)通过使用缓存和其他减少负载的技巧来加速数据库本身。但我不是调优数据库使用的专家。您是否建议在应用程序之前调整数据库?
        • 如果您确定问题出在休眠状态,调整数据库将无济于事。在调整之前,使用分析器工具或其他工具来帮助您准确跟踪性能问题的根源,然后对其进行优化。不幸的是,没有简单的方法。好消息是:现在所有的 IDE 都有不错的分析支持。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-12
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 2015-11-01
        • 2011-07-27
        • 2010-12-20
        相关资源
        最近更新 更多