问题一
在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就是多线程的