2012-12-18 61 views
5

我正在調整我們在App Engine上運行的應用程序,其中一項最大成本是數據存儲讀取和寫入操作。我注意到寫作中最大的罪犯之一就是我們堅持下單的時候。如何優化AppEngine Java/JDO數據存儲put()以減少寫入數量

基本數據是令有許多項目 - 我們都分開存放,並涉及他們這樣的:

@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 request info

一些我知道的,各區域面積可能會幫助:

  1. 較少的索引 - 有一些順序和項目屬性的隱含索引,我可以告訴appengine不要索引,例如item.quantity不是我需要查詢的東西。但是,所有這些寫作都是爲了什麼?
  2. 解除關聯項目和訂單,以便我只有一個實體OrderItem,根本不需要關係(但是需要額外存儲支付)。
  3. 根據明確性指數,我只在訂單表上訂單1,按訂單日期,訂單項上一個,按SKU /日期和關係中的一個表示。
  4. 如果這些項目是一個集合,而不是一個列表,是否會完全刪除對子項_IDX的索引需求?

所以,我的問題是,任何上述項目將預示着大勝利的,還是有我想念那種感覺會更好,最初專注於其他的選擇嗎?

獎勵積分:是否有一個很好的'指南少數據存儲寫'文章的某個地方?

回答

2

Billing docs清楚闡明:

  • 新實體穿戴(每個實體,無論實體大小的):2個寫入+ 2每索引屬性值寫入每個組合索引值

  • 現有+ 1個寫入Entity Put(每個實體):每修改索引屬性值1次寫入+4次寫入+每個修改後的複合索引值寫入2次

  • 同樣相關:App Engine predefines a simple index on each property of an entity.

在給問題:

  1. 是的,寫OPS的數量與指標性的數字。讓他們unindexed to save write ops
  2. 將兩個實體組合在一起會爲您節省1個寫入(或者在新實體的情況下爲2個)。
  3. 您不必爲一個屬性只有「顯式」索引。這些由appengine自動生成。您只需顯式配置複合索引,即可跨越更多屬性。
  4. 編號集合或列表(=訂單集合)只是一種Java表示,Datastore API始終在內部使用列表(=添加的項目保留其順序)。

更新:

索引數影響刻錄的成本,但不是它的速度。 Writes are done in two phases:提交保存實體數據的階段,以及構建索引的階段。 put操作在提交階段後返回並且不受索引數量的影響。

在你的情況下,你是一個接一個地打兩個放。正如你可以從AppStats圖中看到的,它們是連續發生的。您可能想要並行執行它們,如async operations(不確定是否可用於JDO)。

+0

感謝彼得,有沒有4步之外的任何步驟我已經注意到,你會建議尋找,或者我是在正確的軌道上與我的想法。 –

+0

@Ashley:我用最重要的信息更新了答案 - 索引數量影響寫入成本,但不影響寫入速度。爲了加快你的情況,請參閱異步操作。 –