SparkSql小项目练习题来了!趁热乎快来看!!!!

题目

  1. 以下是RNG S8 8强赛失败后,官微发表道歉微博下一级评论
    数据说明:
    rng_comment.txt文件中的数据:
    在这里插入图片描述
数据下载:
链接:https://pan.baidu.com/s/1OvNOmCQgANXfOuMUst0L5A 
提取码:uaz9

1.1.在kafak中创建rng_comment主题,设置2个分区2个副本

bin/kafka-topics.sh --create --zookeeper node01:2181,node02:2181,node03:2181  --replication-factor 2 --partitions 3 --topic rng_comment

1.2.数据预处理,把空行过滤掉

package com.wzy.kafka

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Datas {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("Word").setMaster("local[*]")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")
    val datas = sc.textFile("file:///E:\\SparkCode\\SparkSql\\SparkSqlDya22_0409\\src\\rng.txt")
    datas.filter(x => {
      var file = x.split("\t");
      file.length == 11
    }).coalesce(1).saveAsTextFile("file:///E:\\SparkCode\\SparkSql\\SparkSqlDya22_0409\\src\\new_rng.txt")
  }
}

1.3.请把给出的文件写入到kafka中,根据数据id进行分区,id为奇数的发送到一个分区中,偶数的发送到另一个分区

package com.wzy.kafka;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.io.*;
import java.util.Properties;

public class Producer {
    public static void main(String[] args) throws IOException {
        //1、配置kafka集群
        Properties props = new Properties();

        //kafka服务器地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消息确认机制
        props.put("acks", "all");
        //重试机制
        props.put("retries", 0);
        //批量发送的大小
        props.put("batch.size", 16384);
        //消息延迟
        props.put("linger.ms", 1);
        //批量的缓冲区大小
        props.put("buffer.memory", 33554432);
        //kafka数据中key  value的序列化
        props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");


        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(props);

        String line=null;
        BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("E:\\SparkCode\\SparkSql\\SparkSqlDya22_0409\\src\\new_rng")));
        int partitioner=0;
        while ((line=bufferedReader.readLine())!=null){
            if (Integer.parseInt(line.split("\t")[0])%2==0){
                partitioner=1;
            }else{
                partitioner=2;
            }

            ProducerRecord record = new ProducerRecord("spark_02", partitioner, partitioner + "", line);
            kafkaProducer.send(record);

        }
        bufferedReader.close();
        kafkaProducer.close();



    }
}

1.4.使用Spark Streaming对接kafka
1.5.使用Spark Streaming对接kafka之后进行计算
在mysql中创建一个数据库rng_comment
在数据库rng_comment创建vip_rank表,字段为数据的所有字段

create table vip_rank
(
    indes         varchar(200) null,
    child_comment varchar(200) null,
    comment_time  varchar(200) null,
    content       varchar(200) null,
    da_v          varchar(200) null,
    like_status   varchar(200) null,
    pic           varchar(200) null,
    user_id       varchar(200) null,
    user_name     varchar(200) null,
    vip_rank      varchar(200) null,
    stamp         varchar(200) null
);


在数据库rng_comment创建like_status表,字段为数据的所有字段

create table like_status
(
    indes         varchar(200) null,
    child_comment varchar(200) null,
    comment_time  varchar(200) null,
    content       varchar(200) null,
    da_v          varchar(200) null,
    like_status   varchar(200) null,
    pic           varchar(200) null,
    user_id       varchar(200) null,
    user_name     varchar(200) null,
    vip_rank      varchar(200) null,
    stamp         varchar(200) null
);


在数据库rng_comment创建count_conmment表,字段为 时间,条数

-- auto-generated definition
create table count_conmment
(
    time  varchar(50) null,
    count varchar(50) null
);


1.5.1.查询出微博会员等级为5的用户,并把这些数据写入到mysql数据库中的vip_rank表中
1.5.2.查询出评论赞的个数在10个以上的数据,并写入到mysql数据库中的like_status表中
1.5.3.分别计算出2018/10/20 ,2018/10/21,2018/10/22,2018/10/23这四天每一天的评论数是多少,并写入到mysql数据库中的count_conmment表中

package com.wzy.streaming

import java.sql.DriverManager

import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.{DStream, InputDStream}
import org.apache.spark.streaming.kafka010.{ConsumerStrategies, KafkaUtils, LocationStrategies}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}


object StreamingAndKafka {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("Kafka").setMaster("local[*]")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")
    val ssc = new StreamingContext(sc, Seconds(5))
    //准备连接Kafka的参数
    val kafkaParams = Map[String, Object](
      "bootstrap.servers" -> "node01:9092,node02:9092,node03:9092",
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      "group.id" -> "SparkKafkaDemo",
      //earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
      //latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
      //none:topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
      //这里配置latest自动重置偏移量为最新的偏移量,即如果有偏移量从偏移量位置开始消费,没有偏移量从新来的数据开始消费
      "auto.offset.reset" -> "latest",
      //false表示关闭自动提交.由spark帮你提交到Checkpoint或程序员手动维护
      "enable.auto.commit" -> (false: java.lang.Boolean)
    )
    val topic = Array("spark_02")

   //2.使用KafkaUtil连接Kafak获取数据
    val recordDStream: InputDStream[ConsumerRecord[String, String]] = KafkaUtils.createDirectStream[String, String](ssc,
      LocationStrategies.PreferConsistent,//位置策略,源码强烈推荐使用该策略,会让Spark的Executor和Kafka的Broker均匀对应
      ConsumerStrategies.Subscribe[String, String](topic, kafkaParams))//消费策略,源码强烈推荐使用该策略

var url="jdbc:mysql://localhost:3306/rng_comment?characterEncoding=UTF-8"
    var user="root"
    var password="root"
    //3.获取VALUE数据
    val result: DStream[Array[String]] = recordDStream.map(_.value().split("\t"))
//1.5.1.查询出微博会员等级为5的用户,并把这些数据写入到mysql数据库中的vip_rank表中
    result.filter(x=>x(9)=="5").foreachRDD({
      rdd=>{
        rdd.foreachPartition({
          iter=>({
            val connection = DriverManager.getConnection(url, user, password)
            var sql=
              """
                |insert into
                |vip_rank values
                |(?,?,?,?,?,?,?,?,?,?,?)
                |
                |""".stripMargin
            iter.foreach({
            lien=>{
              val statement = connection.prepareStatement(sql)
              statement.setString(1,lien(0))
              statement.setString(2,lien(1))
              statement.setString(3,lien(2))
              statement.setString(4,lien(3))
              statement.setString(5,lien(4))
              statement.setString(6,lien(5))
              statement.setString(7,lien(6))
              statement.setString(8,lien(7))
              statement.setString(9,lien(8))
              statement.setString(10,lien(9))
              statement.setString(11,lien(10))
              statement.executeUpdate()
              statement.close()
            }
            })
            connection.close()
          })
        })
      }


    })

//1.5.2.查询出评论赞的个数在10个以上的数据,并写入到mysql数据库中的like_status表中
    result.filter(x=>x(5).toInt>10).foreachRDD{
       rdd=>{
         rdd.foreachPartition{
           iter=>{
             val connection = DriverManager.getConnection(url, user, password)
             var sql=
               """
                 |insert into
                 |like_status values
                 |(?,?,?,?,?,?,?,?,?,?,?)
                 |
                 |""".stripMargin
             iter.foreach{
               lien=>{
                 val statement = connection.prepareStatement(sql)
                 statement.setString(1,lien(0))
                 statement.setString(2,lien(1))
                 statement.setString(3,lien(2))
                 statement.setString(4,lien(3))
                 statement.setString(5,lien(4))
                 statement.setString(6,lien(5))
                 statement.setString(7,lien(6))
                 statement.setString(8,lien(7))
                 statement.setString(9,lien(8))
                 statement.setString(10,lien(9))
                 statement.setString(11,lien(10))
                 statement.executeUpdate()
                 statement.close()


               }
             }
             connection.close()
           }
         }

       }

    }
//1.5.3.分别计算出2018/10/20 ,2018/10/21,2018/10/22,2018/10/23这四天每一天的评论数是多少,并写入到mysql数据库中的count_conmment表中
    val timeDataRdd: DStream[Array[String]] = result.filter {
      x => {
        val time: Array[String] = x(2).split(" ")
        //2018/10/20 ,2018/10/21,2018/10/22,2018/10/23
        if (time(0).equals("2018/10/20") || time(0).equals("2018/10/21") || time(0).equals("2018/10/22") || time(0).equals("2018/10/23")) {
          true
        } else {
          false
        }
      }

    }

    timeDataRdd.foreachRDD {
      rdd => {
        rdd.groupBy(x => x(2).split(" ")(0)).map(x => x._1 -> x._2.size).foreachPartition {
          iter => {
            val connection = DriverManager.getConnection(url, user, password)
            var sql =
              """
                |insert into
                |count_conmment values
                |(?,?)
                |
                |""".stripMargin
            iter.foreach {

              lien => {
                val statement = connection.prepareStatement(sql)
                statement.setString(1, lien._1)
                statement.setString(2, lien._2 + "")
                statement.executeUpdate()
                statement.close()
              }
            }
            connection.close()
          }
        }
      }

    }
        ssc.start() //开启
        ssc.awaitTermination() //等待优雅停止

  }
}

发布了218 篇原创文章 · 获赞 330 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/weixin_43563705/article/details/105708116