如何优化AppEngine Java / JDO数据存储区put()以减少写入次数

时间:2012-12-18 00:03:26

标签: java google-app-engine jdo

我正在调整我们在App Engine上运行的应用程序,其中一个最大的成本是数据存储读写。我注意到写作中最大的违规者之一就是我们坚持订单。

基本数据是Order有很多项目 - 我们分别存储它们并将它们关联起来:

@PersistenceCapable
public class Order implements Serializable {

     @Persistent(mappedBy="order")
     @Element(dependent = "true")
     private List<Item> orderItems;

     // other fields too obviously
}

@PersistenceCapable
public class Item implements Serializable {

     @Persistent(dependent = "true")
     @JsonIgnore
     private Order order;

     // more fields...

}

appstats显示了一个带有单个项目的订单的两个数据存储库 - 但两者都使用了大量的写入。我想知道从有经验的人那里优化这个的最好方法。

AppStats数据:

  

real = 34ms api = 1695ms cost = 6400 billed_ops = [DATASTORE_WRITE:64]

     

real = 42ms api = 995ms cost = 3600 billed_ops = [DATASTORE_WRITE:36]

appstats request info

我所知道的一些领域可能有所帮助:

  1. 少了索引 - 在一些订单和商品属性上有隐含的索引,我可以告诉它不要索引,例如item.quantity不是我需要查询的东西。但这就是所有这些写作的内容吗?
  2. 取消关联项目和订单,以便我只有一个实体OrderItem,完全不需要关系(但需要额外的存储空间)。
  3. 就显而易见性指数而言,我在订单表上只有1,按订单日期,订单项目中有一个,按SKU /日期和关系的隐含一个。
  4. 如果这些项目是一个集合,而不是一个列表,是否会完全取消对子项_IDX的索引?
  5. 所以,我的问题是,上述任何项目是否预示着大赢,或者是否有其他选项我错过了最好关注最初?

    奖励积分:某处有一个很好的'指南,以减少数据存储写入文章吗?

1 个答案:

答案 0 :(得分:2)

Billing docs明确指出:

  • 新实体投放(每个实体,无论实体大小):每个索引属性值写入2次+写入+每个复合索引值写入1次

  • 现有实体投放(每个实体):每个修改后的索引属性值写入1次+ 4次写入,每个修改后的复合索引值写入2次

  • 也相关:App Engine predefines a simple index on each property of an entity.

回答问题:

  1. 是,写操作数与索引数属性有关。让他们unindexed to save write ops
  2. 将两个实体组合在一起可以节省1次写入(或者在新实体的情况下为2次)。
  3. 您不需要为一个属性设置“显式”索引。这些是由appengine自动生成的。您只需要显式配置复合索引,跨越更多属性。
  4. 否。集合或列表(=带有顺序的集合)只是一个Java表示,数据存储API总是在内部使用列表(=添加的项目保留其顺序)。
  5. 更新:

    索引数量会影响写入成本但不影响速度。 Writes are done in two phases:提交保存实体数据的阶段,并应用构建索引的阶段。 put操作在提交阶段后返回,不受索引数量的影响。

    在你的情况下,你一个接一个地打两个看跌期权。从AppStats图中可以看出,它们是连续发生的。您可能希望以async operations并行执行它们(不确定在JDO中是否可用)。