我想事先告诉我几个相关问题,如下所示,不解决我的问题:
This one接近但堆栈跟踪不同,无论如何都没有解决。所以请放心,我会在几天(失败的)解决方案之后发布这个问题。
我试图写一份工作,将数据(每天一次)从MySQL
表移动到Hive
表,存储为Parquet
/ ORC
个文件Amazon S3
。有些表非常大:〜300M记录 200 GB +大小(由phpMyAdmin
报告)。
目前我们正在使用sqoop
,但我们希望转移到Spark
,原因如下:
DataFrame API
利用它的功能(将来,我们将在移动数据时执行转换)Scala
中编写了 sizeable 框架,用于组织中其他地方使用的Spark
个工作我已经能够在小型 MySQL
表上实现此目的而没有任何问题。但是,如果我一次尝试获取超过 ~1.5-2M记录,则Spark
作业(将MySQL
中的数据读入DataFrame
)会失败。我已经在下方显示了堆栈跟踪的相关部分,您可以找到完整的堆栈跟踪here。
...
javax.servlet.ServletException: java.util.NoSuchElementException: None.get
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:489)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
...
Caused by: java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:347)
at scala.None$.get(Option.scala:345)
...
org.apache.spark.status.api.v1.OneStageResource.taskSummary(OneStageResource.scala:62)
at sun.reflect.GeneratedMethodAccessor188.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
...
[Stage 27:> (0 + 30) / 32]18/03/01 01:29:09 WARN TaskSetManager: Lost task 3.0 in stage 27.0 (TID 92, ip-xxx-xx-xx-xxx.ap-southeast-1.compute.internal, executor 6): java.sql.SQLException: Incorrect key file for table '/rdsdbdata/tmp/#sql_14ae_5.MYI'; try to repair it
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
...
** 如果移动包含 186M 记录的 148 GB 表失败,则会获得此堆栈跟踪
从(完整)堆栈跟踪中可以看出,Spark
读取作业以None.get
SQLException: Incorrect key for file..
错误后跟MySQL
开始生闷 }(与MySQL
' s false warnings)
现在显然这不是sqoop
问题,因为在这种情况下Spark
也会失败。就numPartitions = 32
而言,我tmp table becoming full设置sqoop
(我们使用40 Spark
的并行度。)
来自BigData
和MySQL
的有限知识, 148 GB 不应压倒性无论如何,对于Spark来说。此外,由于Spark
,EMR
(S3
)和AWS
都位于同一区域(AP-SouthEast
Spark
) ,延迟不应该是瓶颈。
我的问题是:
Spark
是否适用于此工具?Jdbc
Hadoop
驱动程序可能会因此问题受到指责吗?框架配置:
Spark
发布:亚马逊2.8.3 Hive
2.2.1 Scala
2.3.2 EMR
2.11.11 EMR
配置:
1 Master
5.12.0 1 Task
: r3.xlarge [8 vCore,30.5 GiB内存,80 SSD GB存储EBS存储空间:32 GiB] 1 Core
: r3.xlarge [8 vCore,30.5 GiB内存,80 SSD GB存储EBS存储空间:无] clamp <- function(x, low, high)
min(high, max(low, x))
fill1 <- function(df) {
rain <- df$rain
swc <- df$swc
PETc <- df$PETc
SW0 <- df$SW.ini[1]
SW.max <- df$SW.max[1]
SW <- PAW <- aetc <- numeric(nrow(df))
for (day in seq_along(rain)) {
PAW[day] <- SW0 + rain[day]
if (PAW[day] >= swc[day]) {
aetc0 <- PETc[day]
} else {
aetc0 <- (PAW[day] / swc[day]) * PETc[day]
}
aetc[day] <- min(PAW[day], aetc0)
SW0 <- SW[day] <- clamp(PAW[day] - aetc[day], 0, SW.max)
}
list(SW = SW, PAW = PAW, aetc = aetc)
}
: r3.xlarge [8 vCore,30.5 GiB内存,80 SSD GB存储空间
EBS存储:32 GiB] ** 这些是开发集群的配置;生产集群将更好地配备
答案 0 :(得分:0)
Spark JDBC API似乎是fork来将所有数据从MySQL表加载到内存而不是。因此,当您尝试加载大表时,您应该首先使用Spark API克隆数据到HDFS(JSON应该用于保持架构结构),如下所示:
spark.read.jdbc(jdbcUrl, tableName, prop)
.write()
.json("/fileName.json");
然后你可以正常使用HDFS。
spark.read().json("/fileName.json")
.createOrReplaceTempView(tableName);