5

App Engine で実行するアプリを調整していますが、最大のコストの 1 つはデータ ストアの読み取りと書き込みです。書き込みの最大の違反者の 1 つは、注文を固執する場合であることに気付きました。

基本データは Order has many items です。両方を別々に保存し、次のように関連付けます。

@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 は、1 つのアイテムの注文に対して 2 つのデータ ストア プットを示していますが、どちらも大量の書き込みを使用しています。経験のある人からこれを最適化する最良の方法を知りたいです。

AppStats データ:

real=34ms api=1695ms コスト=6400 billed_ops=[DATASTORE_WRITE:64]

real=42ms api=995ms コスト=3600 billed_ops=[DATASTORE_WRITE:36]

appstats リクエスト情報

私が知っている分野のいくつかは、おそらく役立つでしょう:

  1. 少ないインデックス - appengine にインデックスを作成しないように指示できる多数の注文およびアイテム プロパティに暗黙のインデックスがあります。しかし、それがこれらすべての書き込みの目的ですか?
  2. item と order の関連付けを解除して、OrderItem エンティティを 1 つだけ持つようにします。これにより、関連付けの必要がまったくなくなります (ただし、余分なストレージが必要になります)。
  3. 明示的なインデックスに関しては、注文テーブルには注文日ごとに 1 つ、注文アイテムには SKU/日付ごとに 1 つ、暗黙的な関係には 1 つしかありません。
  4. アイテムがリストではなくコレクションである場合、子 _IDX のインデックスは完全に不要になりますか?

それで、私の質問は、上記の項目のいずれかが大きな勝利を告げるものでしょうか、それとも最初に焦点を当てたほうがよい、私が見逃した他のオプションはありますか?

ボーナス ポイント: 「データストアへの書き込みを減らすためのガイド」という優れた記事がどこかにありますか?

4

1 に答える 1

2

請求書には次のように明確に記載されています。

  • New Entity Put (エンティティ サイズに関係なく、エンティティごと): 2 回の書き込み + インデックス付きプロパティ値ごとに 2 回の書き込み + 複合インデックス値ごとに 1 回の書き込み

  • 既存のエンティティ プット (エンティティごと): 1 回の書き込み + 変更されたインデックス付きプロパティ値ごとに 4 回の書き込み + 変更された複合インデックス値ごとに 2 回の書き込み

  • また関連: App Engine は、エンティティの各プロパティに単純なインデックスを事前定義します。

質問へ:

  1. はい、書き込み操作の数は、インデックス プロパティの数に関連しています。書き込み操作を節約するために、それらをインデックスなしにします。
  2. 2 つのエンティティを組み合わせると、書き込みを 1 回 (新しいエンティティの場合は 2 回) 節約できます。
  3. 1 つのプロパティだけに「明示的な」インデックスを付ける必要はありません。これらは appengine によって自動的に生成されます。より多くのプロパティにまたがる複合インデックスを明示的に構成する必要があるだけです。
  4. いいえ。コレクションまたはリスト (= 順序付きのコレクション) は単なる Java 表現です。Datastore API は常に内部的にリストを使用します (= 追加されたアイテムは順序を保持します)。

アップデート:

インデックスの数は書き込みのコストに影響しますが、速度には影響しません。書き込みは 2 つのフェーズで行われます。エンティティ データが保存されるコミット フェーズと、インデックスが作成される適用フェーズです。操作はコミット フェーズのput後に戻り、インデックスの数の影響を受けません。

あなたの場合、2 つの put を次々と呼び出しています。AppStats グラフからわかるように、それらは連続して発生します。それらを非同期操作として並行して実行したい場合があります(JDOで利用できるかどうかはわかりません)。

于 2012-12-18T07:23:20.480 に答える