我正在尝试使用spark将数据从greenplum读取到HDFS中。为此,我使用了jar文件:greenplum-spark_2.11-1.6.0.jar
应用spark.read如下:
val yearDF = spark.read.format("io.pivotal.greenplum.spark.GreenplumRelationProvider").option("url", "jdbc:postgresql://1.2.3.166:5432/finance?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory").option("server.port","8020").option("dbtable", "tablename").option("dbschema","schema").option("user", "123415").option("password", "etl_123").option("partitionColumn","je_id").option("partitions",3).load().where("period_year=2017 and period_num=12 and source_system_name='SSS'").select(splitSeq map col:_*).withColumn("flagCol", lit(0))
yearDF.write.format("csv").save("hdfs://dev/apps/hive/warehouse/header_test_data/")
运行上面的代码时,出现异常:
Exception in thread "qtp1438055710-505" java.lang.OutOfMemoryError: GC overhead limit exceeded
19/03/05 12:29:08 WARN QueuedThreadPool:
java.lang.OutOfMemoryError: GC overhead limit exceeded
19/03/05 12:29:08 WARN QueuedThreadPool: Unexpected thread death: org.eclipse.jetty.util.thread.QueuedThreadPool$3@16273740 in qtp1438055710{STARTED,8<=103<=200,i=19,q=0}
19/03/05 12:36:03 ERROR Executor: Exception in task 0.0 in stage 4.0 (TID 8)
org.postgresql.util.PSQLException: ERROR: error when writing data to gpfdist http://1.2.3.8:8020/spark_6ca7d983d07129f2_db5510e67a8a6f78_driver_370, quit after 2 tries (url_curl.c:584) (seg7 ip-1-3-3-196.ec2.internal:40003 pid=4062) (cdbdisp.c:1322)
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2310)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2023)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:217)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:421)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:318)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:294)
at com.zaxxer.hikari.pool.ProxyStatement.executeUpdate(ProxyStatement.java:120)
at com.zaxxer.hikari.pool.HikariProxyStatement.executeUpdate(HikariProxyStatement.java)
at io.pivotal.greenplum.spark.jdbc.Jdbc$$anonfun$2.apply(Jdbc.scala:81)
at io.pivotal.greenplum.spark.jdbc.Jdbc$$anonfun$2.apply(Jdbc.scala:79)
at resource.AbstractManagedResource$$anonfun$5.apply(AbstractManagedResource.scala:88)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:125)
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:125)
at scala.util.control.Exception$Catch.apply(Exception.scala:103)
at scala.util.control.Exception$Catch.either(Exception.scala:125)
at resource.AbstractManagedResource.acquireFor(AbstractManagedResource.scala:88)
at resource.ManagedResourceOperations$class.apply(ManagedResourceOperations.scala:26)
at resource.AbstractManagedResource.apply(AbstractManagedResource.scala:50)
at resource.DeferredExtractableManagedResource$$anonfun$tried$1.apply(AbstractManagedResource.scala:33)
at scala.util.Try$.apply(Try.scala:192)
at resource.DeferredExtractableManagedResource.tried(AbstractManagedResource.scala:33)
at io.pivotal.greenplum.spark.jdbc.Jdbc$.copyTable(Jdbc.scala:83)
at io.pivotal.greenplum.spark.externaltable.GreenplumRowIterator.liftedTree1$1(GreenplumRowIterator.scala:105)
at io.pivotal.greenplum.spark.externaltable.GreenplumRowIterator.<init>(GreenplumRowIterator.scala:104)
at io.pivotal.greenplum.spark.GreenplumRDD.compute(GreenplumRDD.scala:49)
我按照本官方documentation
中提到的步骤进行了操作我以前使用过jar:greenplum.jar
,它运行良好,但速度较慢,因为它通过GP Master提取数据。
jar:greenplum-spark_2.11-1.6.0.jar
是一个连接器jar,它使用gpfdist
协议将数据提取到HDFS。
此外,异常消息中的IP地址也已更改。您可以看到IP 1.2.3.166:5432
变成了1.2.3.8:8020
,也变成了seg7 ip-1-3-3-196.ec2.internal:40003 pid=4062
使用相同数量的执行程序和执行程序内存,我可以使用greenplum.jar
检索数据。但是,保持一切不变,只是将jar更改为greenplum-spark_2.11-1.6.0.jar
只是为了面对这个异常。
我一直在尝试解决此问题,但我完全不了解这种现象。
谁能让我知道如何解决这个问题?
答案 0 :(得分:0)
Greenplum-Spark连接器旨在并行化Greenplum网段和Spark工作者之间的数据传输。为了充分利用并行数据传输,您必须提供足够的内存和Spark Worker,以加快数据传输速度。否则,您可以使用使用单个JDBC连接器的greenplum.jar通过单个Greenplum主服务器将数据从HDFS加载到Greenplum数据库中。当您将数据加载到单个Greenplum主数据库中时,速度会明显变慢。
一些注意事项:
-根据Greenplum段的数量,您是否有足够的Spark工作者/执行者在Spark和Greenplum集群之间接收或发送数据?
-取决于分配给Spark工作程序/执行程序的内存。引用“ Tuning Spark”文档
从带有此消息“ java.lang.OutOfMemoryError:超出了GC开销限制”的错误日志中,我可以假定您的spark工作者/执行者没有足够的内存。您仍然需要调整Spark工作者,以便可以并行化从HDFS加载数据。
答案 1 :(得分:0)
可以增加分区数量吗?根据表的大小,您可能需要增加分区数。您可以尝试将分区数量增加到30,看看是否仍然遇到内存不足问题吗?
val yearDF = spark.read.format("io.pivotal.greenplum.spark.GreenplumRelationProvider").option("url", "jdbc:postgresql://1.2.3.166:5432/finance?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory").option("server.port","8020").option("dbtable", "tablename").option("dbschema","schema").option("user", "123415").option("password", "etl_123").option("partitionColumn","je_id").option("partitions",30).load().where("period_year=2017 and period_num=12 and source_system_name='SSS'").select(splitSeq map col:_*).withColumn("flagCol", lit(0))
yearDF.write.format("csv").save("hdfs://dev/apps/hive/warehouse/header_test_data/")