2017-10-12 111 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