在这个项目中遇到的一个问题,由于数据库使用的是GREENPLUM,GREENPLUM提供的SPARK驱动是使用的先生成外部表,然后在使用INSERT 表名 SELECT * FROM 外部表的方式方法导入数据的。并且这种方式不支持自增ID。于是我们开始尝试使用SPARK或其他方式生成ID。
1、使用REDIS生成自增ID。
优点:使用REDIS的INCNY实现自增,并且没有并发问题,REDIS集群环境完全可以满足要求。
缺点:因为每次都要去REDIS上取ID,SPARK与REDIS之间每次都是一次网络传输,少则10几ms,多则几百ms。而且SPARK与REDIS形成了依赖关系。一旦REDIS挂了,SPARK就会出现问题。所以我们放弃了这个方案。
2、使用SPARKSQL的函数和withcolumn生成自增ID
val newDf = dataFrame.withColumn("id",org.apache.spark.sql.functions.row_number().over(Window.partitionBy(batch).orderBy(index))
由于上面的代码生成新的dataFrame,分区会变成一个,所以要转成RDD,重新repartition一下。
val newRdd = newDf.rdd.repartition(10)
val df = session.createDataFrame(newRdd,schema)
由于有repartition操作,这里会出现shuffle。所以存在性能问题。对于我们要求大批量快速入库的要求不能满足。所以不能采用。
3、使用zipWithIndex在生成RDD[ROW]时生成ID
val tempRdd = rdd.zipWithIndex()
val record = tempRdd.map(x=>{
var strArray = x._1.split(",")
val newArray = strArray.+:(x._2).toString)
newArray
})
这个方案是参考了下面这个博客弄出来的