如何从MySQL加载大量数据并另存为文本文件?

时间:2017-07-21 08:10:17

标签: scala apache-spark apache-spark-sql

我使用LIMITOFFSET从MySql数据库中获取大量数据,如:

var offset = 0
for (s <- a to partition) {

  val query = "(select * from destination LIMIT 100000 OFFSET " + offset + ") as src"
  data = data.union(spark.read.jdbc(url, query, connectionProperties).rdd.map(_.mkString(","))).persist(StorageLevel.DISK_ONLY)
  offset += 100000
}
val dest = data.collect.toArray
val s = spark.sparkContext.parallelize(dest, 1).persist(StorageLevel.DISK_ONLY).saveAsTextFile("/home/hduser/Desktop/testing")

对于少量数据,它的工作正常,而对于大量数据,它会抛出java.lang.OutOfMemoryError: Java heap space之类的错误,所以如果我能坚持val dest = data.collect.toArray它会按预期工作,抱歉这样一个天真的问题我'新来的火花。

分区方法:

val query = "(select * from destination) as dest"
val options = Map(
"url" -> "jdbc:mysql://192.168.175.35:3306/sample?useSSL=false",
"dbtable" -> query,
"user" -> "root",
"password" -> "root")

val destination = spark.read.options(options).jdbc(options("url"), options("dbtable"), "0", 1, 5, 4, new java.util.Properties()).rdd.map(_.mkString(","))
.persist(StorageLevel.DISK_ONLY).saveAsTextFile("/home/hduser/Desktop/testing")

谢谢

1 个答案:

答案 0 :(得分:2)

  

我正在获取大量数据

这就是你使用Spark的原因,不是吗?:)

 for (s <- a to partition)    
 val dest = data.collect.toArray    
 spark.sparkContext.parallelize(dest, 1)
  

注意: 请勿这样做。我甚至称它为Spark反模式,你加载一个   执行器上的数据集(来自使用JDBC的MySQL)仅用于传输它   向驾驶员发送“大量数据”,然后转移它   返回执行程序将其保存到磁盘。

就像你想要摆脱Spark进行这些网络往返一样。

spark.read.jdbc支持在加载时使用partitionColumnlowerBoundupperBound选项(请参阅JDBC To Other Databases)或(未记录的)对数据集进行分区predicates选项。

  

partitionColumn lowerBound upperBound 描述了在从多个工作人员并行读取时如何对表进行分区。 partitionColumn必须是相关表中的数字列。请注意,lowerBound和upperBound仅用于决定分区步幅,而不是用于过滤表中的行。因此,表中的所有行都将被分区并返回。此选项仅适用于阅读。

让Spark完成其工作。