1.需求
1.在一段时间内到底有多少不同的用户访问了网站。
2.另外一个统计流量的重要指标是网站的独立访客数(Unique Visitor,UV)。
3.UV指的是一段时间(比如一小时)内访问网站的总人数,1 天内同一访客的多次访问只记录为一个访客。
2.代码实现
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.scala.function.AllWindowFunction
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector
//设置输入数据类型
case class userBeh(userId:Long,itemId:Long,categoryId:Int,behavior:String,timestamp:Long)
//设置输出数据的类型
case class UvCount(windowEnd:Long,count:Long)
object UniqueVisitor {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val data = env.readTextFile("E:\\WY\\programme\\MusicProject\\src\\main\\resources\\UserBehavior.csv")
val resultStream = data.map(data => {
val arr = data.split(",")
userBeh(arr(0).toLong, arr(1).toLong, arr(2).toInt, arr(3), arr(4).toLong)
})
.assignAscendingTimestamps(_.timestamp * 1000)
.filter(_.behavior == "pv")
.timeWindowAll(Time.seconds(60 * 60))
.apply(new UvCountByWindow())
resultStream.print()
env.execute()
}
}
//自定义实现全窗口函数,用一个Set结构来保存所有的userId,进行自动去重
class UvCountByWindow extends AllWindowFunction[userBeh,UvCount,TimeWindow] {
override def apply(window: TimeWindow, input: Iterable[userBeh], out: Collector[UvCount]): Unit = {
//自定义一个Set
var idSet = Set[Long]()
//遍历窗口中的所有数据,把userId添加到set中,自动去重
for(userBehavior <- input){
idSet += userBehavior.userId
}
//将set的size作为去重后的uv值输出
out.collect(UvCount(window.getEnd,idSet.size))
}
}