尝试在Apache Spark中持久保存到数据库时,RDD无法正常工作

时间:2017-07-26 06:55:23

标签: hadoop apache-spark apache-spark-sql rdd

我想将我的rdd保存到mysql数据库表中。我使用map函数迭代RDD并将每个元组传递给我的函数,在那里我建立了持久性。在这里,我想将我的工作归化为主节点和从节点。

但它并没有正常工作,也没有调用我使数据库持久化的功能。

如果我使用诸如courseSet.collect().map(m => sendCourseInfo(m))之类的collect()而不是courseSet.map(m => sendCourseInfo(m)),那么这将正常工作。

我不想在这里使用collect()。

我在很多文章中搜索过此内容并且无法弄明白。任何人都可以帮我解决这个问题。

以下是我的代码,

 .....
  x.toString().split(",")(1),
  x.toString().split(",")(2),
  x.toString().split(",")(3)))

 courseSet.map(m => sendCourseInfo(m))
}

def sendCourseInfo(courseData: (Int, String, String, String)): Unit = {
    try {
      DatabaseUtil.setJDBCConfiguration()

      val jdbcConnection: java.sql.Connection = DatabaseUtil.getConnection

      val statement = "{call insert_course (?,?,?,?)}"
      val callableStatement = jdbcConnection.prepareCall(statement)
      callableStatement.setInt(1, courseData._1)
      callableStatement.setString(2, courseData._2)
      callableStatement.setString(3, courseData._3)
      callableStatement.setString(4, courseData._4)

      callableStatement.executeUpdate
    } catch {
      case e: SQLException => println(e.getStackTrace)
    }
}

1 个答案:

答案 0 :(得分:0)

你在RDD上调用map(),这是一个转换,而不是一个动作。所以,要执行它,你需要调用一些动作,如

courseSet.foreach(sendCourseInfo)

对你正在做的事情的额外建议,

无论x是什么,你都将它转换为String,拆分它并从这个拆分中提取一些东西。你正在为RDD / Collection中的每个元素做三次这样的事情。所以,你可以用这样的东西来优化它,

x.map(_.toString.split(",")).map(x=>(x(1),x(2),x(3)))

接下来,在这种情况下,您必须将此数据保存在DB,MySql中。您正在使用java通常的jdbc连接,为每个元素创建新的连接和操作。相反,使用Spark 2.x做这样的事情,

import org.apache.spark.sql.SparkSession
import java.util.Properties

...

case class TableSchema(col1:Int,col2:String,col3:String,col4:String)
val props = new Properties()

def main(args: Array[String]): Unit = {

val ss = SparkSession.builder.appName("Test").master("local[*]").getOrCreate()

import ss.implicits._

...

props.setProperty("username", "username")
props.setProperty("password", "password")    

val df = rdd.map(_.toString.split(",")).map(x=>TableSchema(x(0),x(1),x(2),x(3))).toDF()

df.write.jdbc(s"jdbc:mysql://${mysqlHost}/${mysqlDBName}", "tablename", props)

}

让我知道这是否有帮助,干杯。