spark-DataFrame数据插入mysql性能优化

本文介绍了在Spark项目中遇到DataFrame数据插入MySQL性能问题,通过分析源代码和调整数据库连接参数,实现了批量插入,从而显著提高了数据写入速度。优化后的解决方案使数千条记录的插入从原来的两分钟缩短至几乎瞬间完成。
摘要由CSDN通过智能技术生成

spark-DataFrame数据插入mysql性能优化

简介

最近在公司项目有使用spark做数据处理,数据的结果要求写入到mysql或者tidb。spark在做完一系列的rdd操作后得到的结果通过jdbc方式插入到数据,但是插入的数据非常慢。开始研究这一块的代码和寻找性能优化。

结果插入mysql

spark给我们做了封装,插入mysql的代码使用非常简单,直接调用spark的API即可

df.write.mode(SaveMode.Append).format("jdbc")
       .option("url",getValueOfPrefix(prefix,"url"))  // 数据库连接地址
       .option("isolationLevel","NONE")  // 不开启事务
       .option(JDBCOptions.JDBC_BATCH_INSERT_SIZE,150)  // 设置批次大小
       .option("dbtable", tableName)  // 插入的表
       .option("user",getValueOfPrefix(prefix,"username"))  // 数据库用户名
       .option("password",getValueOfPrefix(prefix,"password"))  // 数据库密码
       .save()

以上代码,运行的速度有点慢,插入几千的记录大概要话费2分钟左右,后来网上找了一些资料。原因很简单,这并没有开启批次插入,虽然代码设置了,但是数据层面没有开启批次查询,需要在数据库连接后再增加一个参数rewriteBatchedStatements=true//启动批处理操作

db.url= "jdbc:mysql://localhost:3306/User? rewriteBatchedStatements=true";

设置完这个参数后,插入几千条记录基本就是秒杀。

源代码解析总结

首先DataFrame会调用write方法,该方法返回一个org.apache.spark.sql.DataFrameWriter对象,这个对象的所有属性设置方法都采用链操作技术方式(设置完成属性后,返回this)

  def write: DataFrameWriter[T] = {
   
    if (isStreaming) {
   
      logicalPlan.failAnalysis(
        "'write' can not be called on streaming Dataset/DataFrame")
    }
    new DataFrameWriter[T](this)
  }

设置完插入属性后,调用save()方法,去执行结果保存。在save方法中,创建了org.apache.spark.sql.execution.datasources.DataSource对象,通过调用DataSource对象的write(mode, df)方法完成保存数据的操作。

  def save(): Unit = {
   
    assertNotBucketed("save")
    val dataSource = DataSource(
      df.sparkSession,
      className = source,
      partitionColumns = partitioningColumns.getOrElse(Nil),
      bucketSpec = getBucketSpec,
      options = extraOptions.toMap)

    dataSource.write(mode, df)
  }

write方法做了2件事情,判断结果保存到数据库,还是保存到文件系统,本次跟踪的是保存结果到数据。

  def write(mode: SaveMode, data: DataFrame): Unit = {
   
    if (data.schema.map
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值