2012-12-18 9 views
5

Sto tuning un'app che eseguiamo su App Engine e uno dei costi maggiori è la lettura e la scrittura di archivi dati. Ho notato che uno dei più grandi delinquenti delle scritture è quando persistiamo un ordine.Come ottimizzare un datastore Java/JDO di AppEngine put() per utilizzare meno scritture

dati di base è Ordine ha molti elementi - abbiamo memorizzare sia separatamente e li rapportiamo questo modo:

@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... 

} 

I appstats sta mostrando due archivio di dati pone per un acquisto di un singolo elemento - ma entrambi stiamo usando massiccia numero di scritture. Voglio sapere il modo migliore per ottimizzare questo da chiunque abbia esperienza.

AppStats dati:

reali = 34ms API = 1695ms costano = 6400 billed_ops = [DATASTORE_WRITE: 64]

reale = 42ms api = 995ms costo = 3600 billed_ops = [DATASTORE_WRITE: 36]

appstats request info

Alcune delle aree che conosco che potrebbe aiutare:

  1. indici in meno - ci sono indici impliciti su un numero di proprietà di ordine e articolo che potrei dire che appengine non indicizzare, ad esempio item.quantity non è qualcosa di cui ho bisogno di eseguire una query. Ma è per quello che sono tutte queste scritture?
  2. de-relate articolo e ordine, in modo da avere solo un'entità singola OrderItem, eliminando la necessità di una relazione (ma pagando con memoria extra).
  3. In termini di indici di probabilità, ho solo 1 sulla tabella ordini, per data dell'ordine, e uno sugli articoli dell'ordine, per SKU/data e l'implicito per la relazione.
  4. Se gli elementi fossero una raccolta, non una lista, eliminerebbero la necessità di un indice sugli _IDX figli interamente?

Quindi, la mia domanda sarebbe: alcuni degli articoli sopra elencati preannunceranno grandi vittorie, o ci sono altre opzioni che ho perso che sarebbe meglio concentrarsi inizialmente?

Punti bonus: C'è una buona guida 'per meno scritture datastore' da qualche parte?

risposta

2

Billing docs chiaramente:

  • Nuova entità Put (per entità, indipendentemente dalle dimensioni dell'ente): 2 scritture + 2 scrive al valore della proprietà indicizzata + 1 scrittura per ogni valore indice composito

  • esistente Entità Put (per entità): 1 scrittura + 4 scritture per valore di proprietà indicizzato modificato + 2 scritture per valore indice composito modificato

  • Importante: App Engine predefines a simple index on each property of an entity.

Su alle domande:

  1. Sì, il numero di ops scrittura è legata al numero di indici proprietà. Falli li unindexed to save write ops.
  2. Combinando due entità insieme si risparmia 1 scrittura (o 2 in caso di nuove entità).
  3. Non è necessario disporre di indici "espliciti" per una sola proprietà. Questi sono generati automaticamente da Appengine. Hai solo bisogno di configurare esplicitamente gli indici composti, estendendo più proprietà.
  4. N. raccolta o lista (= raccolta con ordine) è solo una rappresentazione Java, l'API Datastore utilizza sempre la lista internamente (= gli articoli aggiunti mantengono il loro ordine).

Aggiornamento:

numero di indici incide sui costi di scrittura, ma non la sua velocità. Writes are done in two phases: fase di commit in cui vengono salvati i dati dell'entità e si applica la fase in cui vengono creati gli indici. L'operazione put restituisce dopo la fase di commit e non è influenzata dal numero di indici.

Nel tuo caso stai chiamando due posizioni, una dopo l'altra. Come puoi vedere dal grafico di AppStats, si verificano consecutivamente. Potrebbe essere necessario eseguirli in parallelo come async operations (non sicuro se disponibile in JDO).

+0

Grazie Peter, ci sono dei passaggi al di fuori dei 4 che ho notato che suggeriresti di guardare, o sono sulla buona strada con quello che ho in mente. –

+0

@Ashley: Ho aggiornato la risposta con il bit più importante di informazioni: il numero di indici influisce sul costo di scrittura, ma non sulla velocità di scrittura. Per accelerare le cose nel tuo caso vedi operazioni asincrone. –