【问题标题】:Java datastore write performance: Objectify vs. JPAJava 数据存储写入性能:Objectify 与 JPA
【发布时间】:2015-03-03 23:16:46
【问题描述】:

我针对数据存储运行了两个五分钟长的简单基准测试。一个使用 Google 提供的基于 Datanucleus 的 JPA 实现,另一个使用 Objectify 进行持久化。每个请求创建了 10 个具有相同 9 个字段的新索引实体,每个都使用另一种数据类型。为了避免网络连接造成的任何影响,基准测试返回了 10 次写入开始和结束之间的时间跨度。

平均 中位数 10% 90% 99% JPA 76.5 76 53 98 114 客观化 41.1 40 39 43 57 物化 TX 50.6 50 44 60 69

正如您所见,使用 Objectify 比 JPA 快得多。对于依赖 JPA 的人是否有任何性能提示,或者 App Engine 项目是否应该使用 Objectify 而不是 JPA?

为了提供更多细节,这里是我的 Objectify 代码:

// Objectify
public TimedBenchResult writeIndexedAsyncBenchmark() {
  TimedBenchResult result = new TimedBenchResult();    

  for (int i = 0; i < 10; i++) {
      ofy().save().entity(MyUtils.randomIndexedEntity()).now();
  }    

  result.stop();
  return result;
}

来自 Objectify 文档:

如果您在没有显式事务的情况下对数据存储进行操作,则每个数据存储操作都被视为一个单独的小事务,将单独重试。

所以每个ofy().save().entity() 都在它自己的小事务中。我在 JPA 中尽可能接近的实现如下所示:

// JPA
public TimedBenchResult writeIndexedBenchmark() {
   EntityManager em = EntityManagerSingleton.getEntityManager();    

   TimedBenchResult result = new TimedBenchResult();    

   try {
      for (int i = 0; i < 10; i++) {
          // Transaction needed
          // otherwise too much entity groups are involved
          em.getTransaction().begin();
          em.persist(MyUtils.randomJPAIndexedEntity());
          em.getTransaction().commit();
      }
   } finally {
      em.close();
      result.stop();
   }    

   return result;
}

【问题讨论】:

  • 您可能想试试 Low-level Datastore API 进行比较。
  • 他们提供的东西不一样。谷歌的 JPA 插件提供完整的 JPA 功能、拦截更新等,AFAIK 不在 Objectify 中,这不是对 Objectify 的批评,只是 JPA 拥有它们,如果它们对你有用 - 一切都归结为你想做的事情最合适的。如果您想在不跟踪更改的情况下决定将对象推入/推出数据库,那么请选择 Objectify。除了 Google 的 JPA 插件使用的(不是真正相关的)DataNucleus 项目很久以前 AFAIK 停止使用的古老代码。
  • 即使我不知道 Google 的 JPA for App Engine 的确切实现细节,看起来他们不久前就放弃了该插件。阅读答案后,我现在认为这真的取决于您的应用程序必须做什么。如果它是从 JEE 迁移而来的,或者您必须遵守 Java 标准,那么 JPA 是一个不错的选择。 Objectify 将您锁定在 App Engine 数据存储区,但也显示了最佳的数据存储区感知实施。从性能的角度来看它们很好,但不应影响 JPA 或 Objectify 之间的决定。

标签: google-app-engine jpa google-cloud-datastore objectify


【解决方案1】:

你应该停止担心这个。现实世界的应用程序不太可能被 POJO 到数据存储的映射所支配。选择您希望将时间花在编程上的 API。

您的测试的一个怪癖是因为您的 Objectify 代码使用异步保存,所以您会看到很多在 JPA 测试中没有看到的并发性。 FWIW,无法从 JPA 访问异步 API。

【讨论】:

  • Objectify 示例中有一个错字:我使用了同步 API。我认为如果应用程序必须尽可能快地响应并且
  • 首先,要成为苹果对苹果,摆脱 JPA 代码中的显式事务 - Objectify 文档中的注释也适用于 JPA。其次,Objectify 和 JPA 之间的任何真正区别都只是少量的计算工作,不太可能成为您的 GAE 总账单的主要因素。
  • ...为了清楚起见,我非常喜欢 Objectify - 我写的。但那是因为它有更好的编程模型,而不是出于性能原因。
  • 我同意,afaik 大多数成本节省可以在数据存储中找到并减少不必要的写入。但只是为了记录:我将 Objectify 写入包装在一个事务中,以查看结果是否发生显着变化——它们没有。 JPA 版本与 Objectify 之间仍有差距。所以恕我直言,JPA 的唯一正当理由是使用 JEE 标准技术而不是专有 API 来实现持久性。但即便如此,Datastore JPA 实现也缺少许多 JPA / RDBMS 功能,因为它是无模式 NoSQL 特性(这也可能是性能缺陷背后的原因)。
  • 在大量使用 GAE/J 插件以及它的 JPA 实现和 Objectify 之后,Objectify 最终成为我的首选。使用 JPA 很容易出错,并且有时会在插件的代码中发现错误。另一方面,Objectify 从一开始就是一条更容易的路径。它甚至可以很好地集成到基于 RingoJS 的应用程序中,这对我来说是一个主要的好处。只是想在将近一年后强调这一点;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多