5

我正在调整我们在 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 数据:

真实=34ms api=1695ms 成本=6400 billed_ops=[DATASTORE_WRITE:64]

实际=42ms api=995ms 成本=3600 billed_ops=[DATASTORE_WRITE:36]

appstats 请求信息

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

  1. 更少的索引 - 我可以告诉 appengine 不要索引的一些订单和项目属性的隐含索引,例如 item.quantity 不是我需要查询的东西。但这就是所有这些写作的目的吗?
  2. 取消关联项目和订单,这样我就只有一个实体 OrderItem,完全不需要关系(但需要用额外的存储空间付费)。
  3. 就显式索引而言,我在订单表上只有 1 个,按订单日期,一个在订单项上,按 SKU/日期,隐含一个关系。
  4. 如果这些项目是一个集合,而不是一个列表,那会完全消除对子 _IDX 索引的需要吗?

所以,我的问题是,上述任何项目是否预示着重大胜利,还是我错过了其他一些更好的选择?

加分点:某处是否有很好的“减少数据存储写入指南”文章?

4

1 回答 1

2

计费文档明确指出:

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

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

  • 同样相关:App Engine 为实体的每个属性预定义了一个简单的索引。

关于问题:

  1. 是的,写入操作的数量与索引属性的数量有关。使它们未编入索引以保存写入操作
  2. 将两个实体组合在一起将为您节省 1 次写入(如果是新实体,则为 2 次)。
  3. 您不需要仅为一个属性设置“显式”索引。这些是由 appengine 自动生成的。您只需要显式配置复合索引,涵盖更多属性。
  4. 不。集合或列表(= 有顺序的集合)只是 Java 表示,Datastore API 始终在内部使用列表(= 添加的项目保留其顺序)。

更新:

索引数量会影响写入成本,但不会影响速度。写入分两个阶段完成:保存实体数据的提交阶段和构建索引的应用阶段。操作在提交阶段后返回,put不受索引数量的影响。

在您的情况下,您一个接一个地跟注两个看跌期权。正如您从 AppStats 图表中看到的那样,它们是连续发生的。您可能希望将它们作为异步操作并行执行(不确定在 JDO 中是​​否可用)。

于 2012-12-18T07:23:20.480 回答