2017-10-12 109 views
1

我試圖從星火SQL與下面的代碼連接到Oracle DB:甲骨文引黃星火SQL

val dataTarget=sqlcontext.read. 
  format("jdbc"). 
  option("driver", config.getString("oracledriver")). 
  option("url", config.getString("jdbcUrl")). 
  option("user", config.getString("usernameDH")). 
  option("password", config.getString("passwordDH")). 
  option("dbtable", targetQuery). 
  option("partitionColumn", "ID"). 
  option("lowerBound", "5"). 
  option("upperBound", "499999"). 
  option("numPartitions", "10"). 
  load().persist(StorageLevel.DISK_ONLY) 

默認情況下,當我們通過星火SQL與Oracle連接,它會創建一個分區中的一個連接將爲整個RDD創建。這種方式會導致鬆散的並行性,當表中有大量數據時會出現性能問題。在我的代碼中,我通過了option("numPartitions", "10") 這將創建10個連接。如果我錯了,請更正,如我所知,與Oracle的連接數將等於我們通過的分區數

如果我使用更多連接,則會出現以下錯誤,因爲可能存在Oracle連接限制。

值java.sql.SQLException:ORA-02391:超過了同時 SESSIONS_PER_USER限制

要,如果我用更多的分區創建並行多個分區,錯誤出現,但如果我把我少遇到性能問題。是否有任何其他方式來創建單個連接並將數據加載到多個分區(這將挽救我的生命)。

請建議。

回答

1

是否有任何其他的方法來創建一個單一的連接和數據加載到多個分區

沒有。通常,分區由不同的物理節點和不同的虛擬機進行處理。考慮到所有的授權和認證機制,你不能只是連接並將它從節點傳遞到節點。

如果問題剛剛超過SESSIONS_PER_USER,請聯繫DBA並要求增加Spark用戶的值。

如果問題被限制,您可以嘗試保留相同的數字分區,但減少Spark核心的數量。由於這主要是微操作,所以完全刪除JDBC可能會更好,請使用標準導出機制(COPY FROM)並直接讀取文件。

0

一個解決可能是使用單個Oracle連接(分區),然後簡單地repartition加載數據:

val dataTargetPartitioned = dataTarget.repartition(100); 

還可以通過現場分區(如果partitioning a dataframe):

val dataTargetPartitioned = dataTarget.repartition(100, "MY_COL"); 
+1

正如我以前所說,如果我只使用一個連接,它會影響我的性能,我會鬆散並行 –

+0

您問:「是否有任何其他方式來創建單個連接並將數據加載到多個分區」。我認爲我的方法允許您同時擁有單個Oracle連接和具有多個分區的Dataframe。 – tbone