专栏首页伦少的博客SparkStreaming+Kafka 实现统计基于缓存的实时uv

SparkStreaming+Kafka 实现统计基于缓存的实时uv

前言

本文利用SparkStreaming+Kafka实现实时的统计uv,即独立访客,一个用户一天内访问多次算一次,这个看起来要对用户去重,其实只要按照WordCount的思路,最后输出key的数量即可,所以可以利用SparkStreaming+Kafka 实现基于缓存的实时wordcount程序,这里稍加改动,如果uv数量增加的话就打印uv的数量(key的数量)。

1、数据

数据是我随机在kafka里生产的几条,用户以空格区分开(因为用的之前单词统计的程序)

2、kafka topic

首先在kafka建一个程序用到topic:KafkaUV

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic KafkaUV

3、创建checkpoint的hdfs目录

我的目录为:/spark/dkl/kafka/UV_checkpoint

hadoop fs -mkdir -p /spark/dkl/kafka/UV_checkpoint

4、Spark代码

启动下面的程序

package com.dkl.leanring.spark.kafka

import org.apache.spark.streaming.StreamingContext
import org.apache.spark.sql.SparkSession
import org.apache.spark.streaming.Seconds
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe

object KafkaUV {
  def main(args: Array[String]): Unit = {
    //初始化,创建SparkSession
    val spark = SparkSession.builder().appName("KafkaUV").master("local[2]").enableHiveSupport().getOrCreate()
    //初始化,创建sparkContext
    val sc = spark.sparkContext
    //初始化,创建StreamingContext,batchDuration为5秒
    val ssc = new StreamingContext(sc, Seconds(5))

    //开启checkpoint机制
    ssc.checkpoint("hdfs://ambari.master.com:8020/spark/dkl/kafka/UV_checkpoint")

    //kafka集群地址
    val server = "ambari.master.com:6667"

    //配置消费者
    val kafkaParams = Map[String, Object](
      "bootstrap.servers" -> server, //kafka集群地址
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      "group.id" -> "UpdateStateBykeyWordCount", //消费者组名
      "auto.offset.reset" -> "latest", //latest自动重置偏移量为最新的偏移量   earliest 、none
      "enable.auto.commit" -> (false: java.lang.Boolean)) //如果是true,则这个消费者的偏移量会在后台自动提交
    val topics = Array("KafkaUV") //消费主题

    //基于Direct方式创建DStream
    val stream = KafkaUtils.createDirectStream(ssc, PreferConsistent, Subscribe[String, String](topics, kafkaParams))

    //开始执行WordCount程序

    //以空格为切分符切分单词,并转化为 (word,1)形式
    val words = stream.flatMap(_.value().split(" ")).map((_, 1))
    val wordCounts = words.updateStateByKey(
      //每个单词每次batch计算的时候都会调用这个函数
      //第一个参数为每个key对应的新的值,可能有多个,比如(hello,1)(hello,1),那么values为(1,1)
      //第二个参数为这个key对应的之前的状态
      (values: Seq[Int], state: Option[Int]) => {

        var newValue = state.getOrElse(0)
        values.foreach(newValue += _)
        Option(newValue)

      })

    //共享变量,便于后面的比较是否用新的uv
    val accum = sc.longAccumulator("uv")

    wordCounts.foreachRDD(rdd => {

      //如果uv增加
      if (rdd.count > accum.value) {
        //打印uv
        println(rdd.count)
        //将共享变量的值更新为新的uv
        accum.add(rdd.count - accum.value)
      }
    })

    ssc.start()
    ssc.awaitTermination()

  }

}

5、生产几条数据

随便写几条即可

bin/kafka-console-producer.sh --broker-list ambari.master.com:6667 --topic KafkaUV

6、结果

根据结果可以看到,既做到了历史消息用户的累计,也做到了用户的去重

本文由 董可伦 发表于 伦少的博客 ,采用署名-非商业性使用-禁止演绎 3.0进行许可。

非商业转载请注明作者及出处。商业转载请联系作者本人。

本文标题:SparkStreaming+Kafka 实现统计基于缓存的实时uv

本文链接:https://dongkelun.com/2018/06/25/KafkaUV/

--------------------

作者联系方式:

QQ:1412359494

微信:dongkelun

--------------------

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SparkStreaming+Kafka 实现基于缓存的实时wordcount程序

    董可伦
  • Spark Streaming连接Kafka入门教程

    转载请务必注明原创地址为:https://dongkelun.com/2018/05/17/sparkKafka/

    董可伦
  • spark ML之特征处理(1)

    转载请务必注明原创地址为:https://dongkelun.com/2018/05/17/sparkMlFeatureProcessing1/

    董可伦
  • SparkStreaming+Kafka 实现基于缓存的实时wordcount程序

    董可伦
  • Vue.js小白速成手册01

    建议安装visual Studio Code,下载地址:https://code.visualstudio.com/

    剽悍一小兔
  • 我是如何一步一步监控公司MySQL的每一个操作?

    canal是一款基于数据库增量日志解析,提供增量数据订阅与消费的框架,整个框架纯JAVA开发,目前仅支持Mysql和MariaDB(和mysql类似)。

    程序员内点事
  • Unity Shader 屏幕后效果——高斯模糊

    https://www.cnblogs.com/koshio0219/p/11137155.html

    汐夜koshio
  • 万字分享,我是如何一步一步监控公司MySQL的?

    在家远程办公第三周,快被手机上的消息搞的有些神经质了,生怕错过一条有用的信息,没办法形势如此,公司摇摇欲坠大家也都如履薄冰,毕竟这时候失业有点惨(穷怕了)。

    程序员内点事
  • [717]canal的安装及配置

    canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

    周小董
  • MySQL如何实时同步数据到ES?试试这款阿里开源的神器!

    canal主要用途是对MySQL数据库增量日志进行解析,提供增量数据的订阅和消费,简单说就是可以对MySQL的增量数据进行实时同步,支持同步到MySQL、Ela...

    用户4172423

扫码关注云+社区

领取腾讯云代金券