Oracle 与 Spark SQL 的连接

Posted

技术标签:

【中文标题】Oracle 与 Spark SQL 的连接【英文标题】:Oracle connetion with Spark SQL 【发布时间】:2017-10-12 11:54:32 【问题描述】:

我正在尝试使用以下代码从 Spark SQL 连接到 Oracle DB:

 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)

默认情况下,当我们通过 Spark 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) 并直接读取文件。

【讨论】:

【参考方案2】:

一种解决方法可能是使用单个 Oracle 连接(分区)加载数据,然后只需 repartition:

val dataTargetPartitioned = dataTarget.repartition(100);

您也可以按字段进行分区(如果partitioning a dataframe):

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

【讨论】:

正如我之前所说,如果我只使用一个连接,它会影响我的性能并且我会失去并行性 您问过这个问题:“有没有其他方法可以创建单个连接并将数据加载到多个分区中”。我认为我的方法允许您同时拥有单个 Oracle 连接和具有多个分区的 Dataframe。

以上是关于Oracle 与 Spark SQL 的连接的主要内容,如果未能解决你的问题,请参考以下文章

SQL Developer连接oracle报错ORA-12514

SQL Developer连接oracle报错ORA-12514

命令行oracle ora-12170:tns:连接超时 ,pl/sql可以连接

oracle11g sql dever链接提示ora-12505,sql plus可以正常连接

oracle执行存储过程时报:ORA-12170:TNS:连接超时

pl/sql远程连接别人oracle数据库时,报错:ora-01034:oracle not available;ora-27101 shared memory rea