问候,
我在Amazon EC2中创建了一个Spark 2.1.1集群,实例类型为m4.large,其中有1个主服务器和5个从属服务器启动。我的 PostgreSQL 9.5 数据库(t2.large)包含一个我要处理的超过20亿行和7列的表。我遵循了Apache Spark网站和其他各种来源中关于如何连接和处理这些数据的指导。
我的问题是Spark SQL性能比我的数据库要慢得多。我的sql语句(请参见下面的代码)在PSQL中大约需要21分钟,而Spark SQL大约需要42分钟才能完成。我的主要目标是衡量PSQL与Spark SQL的性能,到目前为止,我还没有获得期望的结果。我会很感激的。
谢谢
我尝试将fetchSize从10000增加到100000,缓存数据帧,将numpartition增加到100,将spark.sql.shuffle设置为2000,将群集大小加倍,并使用更大的实例类型,到目前为止,我还没有看到任何改进
val spark = SparkSession.builder()
.appName("Spark SQL")
.getOrCreate();
val jdbcDF = spark.read.format("jdbc")
.option("url", DBI_URL)
.option("driver", "org.postgresql.Driver")
.option("dbtable", "ghcn_all")
.option("fetchsize", 10000)
.load()
.createOrReplaceTempView("ghcn_all");
val sqlStatement = "SELECT ghcn_date, element_value/10.0
FROM ghcn_all
WHERE station_id = 'USW00094846'
AND (ghcn_date >= '2015-01-01' AND ghcn_date <= '2015-12-31')
AND qflag IS NULL
AND element_type = 'PRCP'
ORDER BY ghcn_date";
val sqlDF = spark.sql(sqlStatement);
var start:Long = System.nanoTime;
val num_rows:Long = sqlDF.count();
var end:Long = System.nanoTime;
println("Total Row : " + num_rows);
println("Total Collect Time Lapse : " + ((end - start) / 1000000) + " ms");
答案 0 :(得分:2)
没有充分的理由让此代码在Spark上运行比单独使用数据库更快。首先,它甚至没有分发,因为您犯了和您don't partition the data之前一样的错误。
但是更重要的是,您实际上是从数据库中加载数据-结果,它必须至少完成尽可能多的工作(实际上更多),然后通过网络发送数据,然后数据必须由Spark解析,并进行处理。您基本上会做更多的工作,并期望事情会更快-这是不会发生的。
如果您想可靠地提高Spark的性能,则至少应:
那么您可能会有更好的缺乏。但是同样,在群集上对数据进行适当的索引编制也可以提高性能,而总成本可能更低。
答案 1 :(得分:1)
从SQL读取时设置 partitionColumn 非常重要。它用于并行查询。因此,您应该确定哪一列是您的partitionColumn。
例如,您的情况:
val jdbcDF = spark.read.format("jdbc")
.option("url", DBI_URL)
.option("driver", "org.postgresql.Driver")
.option("dbtable", "ghcn_all")
.option("fetchsize", 10000)
.option("partitionColumn", "ghcn_date")
.option("lowerBound", "2015-01-01")
.option("upperBound", "2015-12-31")
.option("numPartitions",16 )
.load()
.createOrReplaceTempView("ghcn_all");
更多参考: