为什么spark应用程序会崩溃并出现异常java.net.socketexception:即使在提供了足够的内存和分区之后连接也会重置?

6rqinv9w  于 2021-07-12  发布在  Spark
关注(0)|答案(1)|浏览(322)

我正在尝试将一个表从sqlserver数据库加载到bigquery,该表的大小为27gb、2.18亿行和28列。
源表没有任何列包含唯一值,以便spark对传入数据进行均匀分区。因此,我对我正在读取的数据应用了row\ u number(),如下所示:

spark = SparkSession.builder.appName('Read_from_Source').getOrCreate()
dataframe = spark.read.format('jdbc').option('url', URL).option('driver', 'con.microsoft.sqlserver.jdbc.SQLServerDriver).
            option('user', user).
            option('password', password).
            option('dbtable', f'select *, row_number() over(ORDER BY (SELECT 1)) as row_num from {tablename}) as temp_load').
            option('partitionColumn',row_num).
            option('numPartitions', 400).
            option('lowerBound', 1).
            option('upperBound', countOfNumOfRows).
            load()
dataframe.write.format('bigquery').option('table','tablename').mode('overwrite').save()

我为作业提供了以下配置:

> spark.submit.deployMode = Cluster 
> spark.executor.instances=4
> spark.execuor.memory=2g spark.executor.cores=4 spark.driver.memory=2g
> spark.network.timeout=240

当我提交的工作,它开始很好,但一段时间后,若失败了一个例外 connection reset 可以在下面看到。

Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:1981)

下面可以看到执行者和舞台。执行者在此处输入图像描述

我工作的阶段(只有一个阶段,因为它只是读取和加载):

我以为在读取数据时连接正在断开/中断,因此出现了连接重置异常。所以我尝试将spark.network.timeout增加到100000,并将numpartitions从200增加到400。错误仍然是一样的。
我还将executor示例增加到6个(我有2个工作节点),executor内存增加到6gb,驱动内存增加到4gb。我仍然看到同样的问题。
我在这里应用分区来读取数据,以避免数据倾斜。给出的记忆也很高。
edit1:这里没有数据发送到驱动程序,因为给定的行是我正在运行的唯一代码。
我设计代码的方式有什么问题吗?有人能给我建议一个解决这个异常的方法吗?

piztneat

piztneat1#

似乎您正在使用至少200个分区从SQLServer读取数据。sql server可能无法处理这么多这样大小的并发查询,并删除/重置连接。
如果是这种情况,那么要解决这个问题,您需要减少spark job的并行性(分区的数量可以相同,但执行器/集群节点的数量要小一些,以减少并发性)或增强(硬件或配置)sql server,以便它能够处理更高的负载或更并发的大型查询。
另外,您可能希望尝试禁用集群上的conscrypt:googledataproc到sqlserver(基于centos7)的连接错误?
一般来说,您应该使用apachesqoop之类的工具从sqlserver导出数据。

相关问题