2015-04-23 129 views
3

我知道幾周前更新了CDF服務(默認工作人員類型&附加的PD已更改),並明確表示它會使批處理作業變慢。然而,我們的工作表現已經下降,超出了他們實際滿足我們業務需求的程度。例如,對於我們的其中一個工作,它從BigQuery中的表中讀取約270萬行,具有6個側面輸入(BQ表),進行一些簡單的字符串轉換,最後寫入多個輸出(3)到BigQuery。這個過去需要5-6分鐘,現在需要15-20分鐘的時間 - 無論我們有多少虛擬機在使用它。數據流性能問題

有什麼我們可以做的,以獲得速度回到我們以前看到的?

下面是一些統計:

  1. 從BQ表讀取與2744897行(294MB)
  2. 6 BQ側輸入
  3. 3多輸出到BQ,其中2個是2744897和其他1500行
  4. 在區亞太east1-b運行下面
  5. 時間包括工作池自旋向上和拆除

10個虛擬機(N1-STANDARD-2) 16分鐘5秒 2015-04-22_19_42_20-4740106543213058308

10個虛擬機(N1-STANDARD-4) 17分11秒 2015 - 04-22_20_04_58-948224342106865432

10個虛擬機(N1-STANDARD-1) 18分鐘44秒 2015-04-22_19_42_20-4740106543213058308

20倍的VM(N1-STANDARD-2) 22分鐘53秒 2015-04-22_21_26_53-18171886778433479315

50倍的VM(N1-STANDARD-2) 17分26秒 2015-04 -22_21_51_37-16026777746175810525

100層的虛擬機(N1-STANDARD-2) 19分鐘33秒 2015-04-22_22_32_13-9727928405932256127

+0

我查看了其中一個作業的步驟執行日誌,看起來大部分時間(大約9分鐘)已用於將步驟已寫入的數據導入BQ。我們將研究爲什麼這個導入過程變得如此緩慢。 – jkff

+0

有沒有一種解決方法,我可以使用,直到你找出爲什麼它變得如此緩慢? –

+0

一位隊友認爲,緩慢可能是由於新SDK對待邊界輸入的方式發生了變化 - 請問您可以參考http://stackoverflow.com/questions/29718820/why-did-sideinput-method-從上下文轉移到processcontext-in-dataflow-beta並檢查它是否與您的工作相關? – jkff

回答

2

我們追查到了這個問題。這是當側面輸入從正在傳輸數據的BigQuery表中讀取而不是批量加載時。當我們複製表格並從副本讀取時,一切正常。

但是,這只是一種解決方法。數據流應該能夠處理BigQuery中的流式表作爲側面輸入。

4

證據似乎表明您的管道如何處理側面輸入存在問題。具體而言,主輸入的每個元素都可能重複從BigQuery中重新讀取副輸入。這與Dataflow工作人員使用的虛擬機類型的更改完全正交,如下所述。

這與Dataflow SDK for Java版本0.3.150326中所做的更改密切相關。在該版本中,我們更改了側面輸入API以適用於每個窗口。現在調用sideInput()現在僅在與主輸入元素的窗口相對應的特定窗口中返回值,而不是整個側面輸入PCollectionView。因此,sideInput()不能再從startBundlefinishBundle中調用DoFn,因爲該窗口尚不知道。

例如,下面的代碼片段有一個問題,會導致每個輸入元素重新讀取側面輸入。

@Override 
public void processElement(ProcessContext c) throws Exception { 
    Iterable<String> uniqueIds = c.sideInput(iterableView); 

    for (String item : uniqueIds) { 
    [...] 
    } 

    c.output([...]); 
} 

此代碼可以通過緩存側輸入到在高速緩存List代替側輸入變換(假定它能夠裝入內存)在第一次調用processElement期間,和使用一個List成員變量來改善隨後的調用。

此替代方法應恢復您之前看到的性能,此時可從startBundle調用副輸入。長期來看,我們將致力於更好地緩存副作用。 (如果這不利於全面解決該問題,請通過電子郵件與我們聯絡,分享相關的代碼片段。)


另外,有,的確,更新至約4雲數據流服務/ 9/15更改了Dataflow工作人員使用的默認虛擬機類型。具體而言,我們減少了每個工作人員的內核缺省數量,因爲我們的基準測試顯示它對於典型作業而言具有成本效益這是而不是任何類型的數據流服務都會減速 - 默認情況下,它只是在每個工作人員的資源較少的情況下運行。用戶仍然可以選擇覆蓋工作人員數量以及工作人員使用的虛擬機類型。

+0

這就是我們已經做的事情 - 我們在processElement()中讀取一次側面輸入,並將結果緩存在內部變量(在我們的例子中是一個HashMap),並將其用於每次後續調用processElement()。在最新發布之前,這一切都正常工作。 –

+1

不,不會爲每次調用processElement()時創建一個'ParDo'的新實例。這將打破捆綁的目的。然而,你的經驗證據似乎表明了這方面的一些東西。我將單獨與您聯繫,讓我們在回到底部時發表一個答案。 –