spark处理时间(java.util.Date)转换为字符串出现不合理日期(02-31)

问题一

在spark里使用 rdd.map 做准换时,其中有一个时间字段(列), 需要将java.util.Date类型转换为字符串类型,进行对表insert。
转换时出现了 2021-02-31这种非法日期,从而导致入库失败

 

package com.scala01

import java.text.SimpleDateFormat
import java.util.Date

import org.apache.spark.sql.{DataFrame, Dataset, SaveMode, SparkSession}
import com.pojo.Hist
import org.apache.spark.rdd.RDD
/**
 * @Author: bai
 * @CreateTime: 2021/10/11 13:21
 * @Company:
 * @Description:
 *              将df 通过jdbc写到 tbase
 */
object Spark02_histToTbase {

  //spark为多线程 不建议使用全局
  //val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  def main(args: Array[String]): Unit = {

    var num:Int =10000000;
    if (args.length==1){
      num=Integer.valueOf(args(0))
    }


    val spark = SparkSession.builder()
      //.master("local[*]")
      .appName("InsertTbase")
      .getOrCreate()
    import spark.implicits._


    /* 有问题会出现 不合理日期
    val rdd2 = spark.sparkContext.makeRDD(1 to num)
      .map(x=> {Hist.ToData()})
      // 使用SimpleDateFormat将Date类型转换为字符串,会出现2021-02-31 这种不合法日期
      .map(x=>{  val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                 // 这种形式会出现 2021-02-31 不合理日期
                 hist(x.getUuid,x.getIp,x.getItem,sdf.format(x.getDt),x.getNum,x.getInfo)})*/

    val rdd = spark.sparkContext.makeRDD(1 to num)
              .map(x=> {Hist.ToData()})
              // 使用SimpleDateFormat将Date类型转换为字符串,会出现2021-02-31 这种不合法日期
              .map(x=>{val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //val ts:Long=x.getDt.getTime
                val dt=sdf.format(x.getDt) // 这种形式不会出现 不合理日期
                //if(1614528557000L<ts&&ts<1614787157000L){println(s"$dt : $ts")} // 将处于 2021-02-28 00:00:00 ~ 2021-02-31 23:59:00之间的时间 单独打出来
                hist(x.getUuid,x.getIp,x.getItem,dt,x.getNum,x.getInfo)})

    val df=rdd.toDF()
    df.show(20,false)

    df.write.format("jdbc")
      .mode(SaveMode.Append)
      .option("driver","org.postgresql.Driver")
      .option("dbtable","hist0")
      .option("url","jdbc:postgresql://1.1.1.1:5432/tmp?binaryTransfer=false&stringtype=unspecified")
      .option("user","xxxx")
      .option("password","xxxx")
      .option("batchsize",100)
      .save()
    spark.close()
  }
  case class hist(uuid: String, ip: String, item: String, dt: String, num: Double, info: String)
}

问题二

/*
在spark中报错
    Caused by: java.lang.NumberFormatException: multiple points
原因是: SimpleDateFormat 在多线程中不安全
 */
//private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

将SimpleDateFormat sdf 声明为static 这是一个全局的 在多线程下会有问题。

spark 多线程的理解:

spark配置 :
spark.executor.instances    2 意思是:启动2个container
spark.executor.cores    4    意思是:一个container中 会启动 4个线程

总共启动8个task,每个container启动4个task,这4个task就是多线程的

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值