【问题标题】:Batch insert using JPA/Toplink使用 JPA/Toplink 批量插入
【发布时间】:2010-09-09 01:13:11
【问题描述】:

我有一个通过 HTTP 接口接收消息的 Web 应用程序,例如:

http://server/application?source=123&destination=234&text=hello

此请求包含发件人的 ID、收件人的 ID 和消息的文本。

此消息应按如下方式处理:

  • 从数据库中查找源和目标的匹配用户对象
  • 创建对象树:包含消息文本字段的 Message 和用于源和目标的两个 User 对象
  • 将此树保存到数据库中。

树将被我无法触及的其他应用程序加载。

我使用 Oracle 作为后备数据库,使用 JPA 和 Toplink 进行数据库处理任务。如果可能的话,我会留在这些地方。

无需太多优化,我就可以在我的环境中实现约 30 个请求/秒的吞吐量。这并不多,我需要约 300 个请求/秒。所以我测量了性能瓶颈在哪里,发现对em.persist() 的调用占用了大部分时间。如果我简单地注释掉那一行,吞吐量会超过 1000 个请求/秒。

我尝试编写一个小型测试应用程序,它使用简单的 JDBC 调用将 100 万条消息持久保存到同一个数据库。我使用了批处理,这意味着我做了 100 次插入然后提交,并重复直到所有记录都在数据库中。在这种情况下,我测量了大约 500 个请求/秒的吞吐量,这可以满足我的需求。

很明显,我需要在这里优化插入性能。但是,正如我之前提到的,我想继续使用 JPA 和 Toplink,而不是纯 JDBC。

您知道使用 JPA 和 Toplink 创建批量插入的方法吗?您能否推荐任何其他提高 JPA 持久性能的技术?

附加信息:

“requests/sec”在这里表示:请求总数/从测试开始到最后一条记录写入数据库的总时间。

我尝试通过在 servlet 内容和持久化程序之间创建一个内存队列来异步调用 em.persist()。对演出有很大帮助。但是队列确实增长得非常快,因为应用程序将连续接收约 200 个请求/秒,这对我来说不是一个可接受的解决方案。

在这种分离的方法中,我收集了 100 毫秒的请求,并在提交事务之前对所有收集的项目调用了 em.persist()。 EntityManagerFactory 在每个事务之间缓存。

【问题讨论】:

    标签: java oracle jpa toplink


    【解决方案1】:

    您对“请求/秒”的衡量标准是多少?换句话说,第 31 个请求会发生什么?什么资源被阻止了?如果是前端/servlet/web部分,能不能在另外一个线程中运行em.persist()立即返回?

    另外,您是否每次都创建交易?您是否为每个请求创建 EntityManagerFactory 对象?

    【讨论】:

      【解决方案2】:

      您应该与 JPA 接口分离并使用裸 TopLink API。您可能可以将您坚持的对象放入 UnitOfWork 并按您的计划提交 UnitOfWork(同步或异步)。请注意, em.persist() 的成本之一是整个对象图发生的隐式克隆。如果您自己 uow.registerObject() 您的两个用户对象,TopLink 会更好地工作,从而节省了它必须做的身份测试。所以你最终会得到:

      uow=sess.acquireUnitOfWork();
      for (job in batch) {
       thingyCl=uow.registerObject(new Thingy());
       user1Cl=uow.registerObject(user1);
       user2Cl=uow.registerObject(user2);
       thingyCl.setUsers(user1Cl,user2Cl);
      }
      uow.commit();
      

      顺便说一句,这是非常古老的 TopLink ;)

      请注意,批处理将有很大帮助,因为批处理写入,尤其是带有参数绑定的批处理写入将会启动,对于这个简单的示例,这可能会对您的性能产​​生非常大的影响。

      需要注意的其他事项:您的测序大小。在 TopLink 中编写对象的大部分时间实际上都花在了从数据库中读取序列信息上,尤其是对于小的默认值(我的序列大小可能有几百甚至更多)。

      【讨论】:

      • 谢谢,我过几天试试。测序大小是什么意思?
      猜你喜欢
      • 2011-11-13
      • 1970-01-01
      • 2011-02-15
      • 2010-10-01
      • 2023-04-03
      • 2016-11-20
      • 2012-12-23
      • 2021-06-05
      • 2018-05-17
      相关资源
      最近更新 更多