關注公衆號:分享電腦學習
回覆"百度雲盤" 可以免費獲取所有學習文檔的代碼(不定期更新)
雲盤目錄說明:
tools目錄是安裝包
res 目錄是每一個課件對應的代碼和資源等
doc 目錄是一些第三方的文檔工具
承接上一篇文檔《Spark案例練習-PV的統計》
參數說明:
繼續上面的PV代碼編寫即可
思路:UV的計算
1.數據進行過濾清洗,獲取兩個字段(時間、guid)
2.guid非空,時間非空,時間字符串的長度必須大於10
3.將同一天的數據放在一起,根據guid去重,統計去重的結果
代碼:
val rdd2 = rdd.map(line => line.split("\t"))
.filter(arr => {
//保留正常數據
arr.length >=3 && arr(2).trim.nonEmpty && arr(0).trim.length > 10
})
.map(arr => {
val date = arr(0).trim.substring(0,10)
val guid = arr(2).trim
(date,guid) // (date,url)
})
繼續編寫代碼
有兩種方式:
1. 基於groupByKey進行UV的統計
2. 基於reduceByKey實現UV的統計
先看基於groupByKey進行UV的統計
val uvRdd = rdd2.groupByKey()
.map(t => {
val date = t._1
val guids = t._2
val uv = guids.toSet.size
(date,uv)
})
println("uv------------------" + uvRdd.collect().mkString(";"))
再看基於reduceByKey實現UV的統計
rdd2.map(t => {
((t._1,t._2),1)
})
.reduceByKey(_+_)
.map(_._1)
val uvRDD: RDD[(String, Int)] = rdd2.distinct()
.map(t => (t._1, 1))
.reduceByKey(_+_)
println("uv------------------" + uvRDD.collect().mkString(";"))
最終指標的合併
val pvuvRdd = pvRdd.fullOuterJoin(uvRdd)
.map(t => {
val date = t._1
val pv = t._2._1.getOrElse(0) //如果有值則返回對應的值,如果無值則返回0
val uv = t._2._2.getOrElse(0)
//返回結果
(date,pv,uv)
})
打印一下,可以看到合併的數據
數據輸出(Driver、保存HDFS上,保存到RDBMS中)
數據返回給Driver
val result = pvuvRdd.collect()
保存到HDFS上
pvuvRdd.saveAsTextFile(s"hdfs://master:9000/data/pv_uv/${System.currentTimeMillis()}")
端口注意下,如果想用域名(master)就要確保在本地hosts文件配置了(win環境下)
運行一下,可以看到hdfs上有了這個文件
保存到RDBMS中、保存到非關係型數據庫中
建庫建表
CREATE DATABASE spark_test;
USE spark_test;
CREATE TABLE pvuv(
`date` DATE NOT NULL,
`pv` INT(11) NOT NULL,
`uv` INT(11) NOT NULL
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
編寫代碼
其中val conn = DriverManager.getConnection("","","")這句話是url、user和password
代碼
pvuvRdd.foreachPartition(iter => {
//1. 創建數據庫連接對象
//2. 創建數據輸出prepareStatement對象
val conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/spark_test","root","root")
val pstmt = conn.prepareStatement("insert into pvuv(date,pv,uv) values(?,?,?);")
//3. 數據迭代輸出
iter.foreach(t => {
val date = t._1
val pv = t._2
val uv = t._3
pstmt.setString(1,date)
pstmt.setInt(2,pv)
pstmt.setInt(3,uv)
pstmt.executeUpdate()
})
//4. 關閉連接
conn.close()
pstmt.close()
})
運行代碼,查看數據庫