//创建sparkSession
val sparkConf = new SparkConf().setAppName("dwd_member_import").setMaster("local[*]")
val sparkSession = SparkSession.builder().config(sparkConf).enableHiveSupport().getOrCreate()
val ssc = sparkSession.sparkContext
//开启动态分区
sparkSession.sql("set hive.exec.dynamic.partition=true")
//开启非严格模式
sparkSession.sql("set hive.exec.dynamic.partition.mode=nonstrict")
//开启压缩
sparkSession.sql("set mapred.output.compress=true")
sparkSession.sql("set hive.exec.compress.output=true")
import sparkSession.implicits._ //隐式转换,调用toDF的操作必须用到隐式转换
//设置hadoop高可用地址,此时需要下载hadoop的三个配置文件(core-site,hdfs-site,hive-site)到resource目录下中,此时clean一下,保证编译后的文件中有我们刚加入的配置文件,
ssc.hadoopConfiguration.set("fs.defaultFS", "hdfs://nameservice1")
ssc.hadoopConfiguration.set("dfs.nameservices", "nameservice1")
val result = ssc.textFile("/hive/ods/baseadlog.log").filter(item => {
//过滤代码
}).mapPartitions(partition => { //mapPartitions按照分区进行迭代,比起map增加了并行度
partition.map(item => {
//转换城json格式,ParseJsonData时我自己定义的一个转换方法,需要自定义
val jsonObject = ParseJsonData.getJsonData(item)
//得到json中的字段名
val adid = jsonObject.getIntValue("adid")
val adname = jsonObject.getString("adname")
val dn = jsonObject.getString("dn")
//返回一个元组,这里注意元组的最大长度为22,超过22需要用样例类case class代替
(adid, adname, dn)
})
}).toDF()//隐式转换就是为了这里的.toDF()能正常用
.coalesce(1) //缩小分区,实质是为了减少文件个数,文件个数和分区有关,对应增大分区的算子.repartition(),.repartition()会重新进行shuffle,而coalesce不会进行shuffle
//coalesce(1)算子中传的值必须小于原有分区个数,不然没有实际意义,没有效果
.write.mode(SaveMode.Overwrite) //mode为Overwrite,在原有数据上进行覆盖,只会覆盖当前分区的数据(一般数仓中实体表会用overwrite),mode为append时在原有数据上面进行追加
//savaAsTable和insertInto
//根据字段名匹配,与字段顺序无关,但是会重新创建一张表,所以数仓一般不会用这个
//insertInto严格按照顺序,会将数据追加到已经有的表中
.insertInto("dwd.dwd_base_ad")//数据插入到已经创建好的hive表中