pvuv的代码开发及提交spark程序jar包运行读取数据源并将结果写入MySQL中


PvUvToMysql类

package com.fuyun.bigdate.spark

import java.sql.{Connection, PreparedStatement}

import org.apache.spark.storage.StorageLevel
import org.apache.spark.{SparkConf, SparkContext}

/**
  * 统计PVUV将结果保存到MySQL中.
  */
object PvUvToMysql {

  def main(args: Array[String]): Unit = {
    /**
      * 初始化
      */
    // 实例化sparkconf并设置程序运行名称
    val sparkConf = new SparkConf().setAppName("pvuv")
    //  实例化sparkcontext并将sparkconf传入
    val sc = new SparkContext(sparkConf)
    // 设置日志级别
    sc.setLogLevel("WARN")
    /**
      * 输入
      */
    //  读取输入文件的内容,并设置分区数为4
    val inputRdd = sc.textFile("hdfs://192.168.xxx.xx/datas/2015082818.data",4)
    //  打印文件内容的第一行
    println(s"first = ${inputRdd.first()}")
    //  统计文件的行数
    println(s"count = ${inputRdd.count()}")
    /**
      * 转换
      */
    // 先将输入的每行去除首尾空格,再保留长度大于0的元素
    val filterRdd = inputRdd.filter(_.trim.length > 0)
      .map(line => {
        //  将每行数据按"\t"分割
        val arr = line.split("\t")
        // 返回date、url、guid
        (arr(17).substring(0, 10),arr(1), arr(5))
      })
    // 缓存
    filterRdd.persist(StorageLevel.MEMORY_AND_DISK_SER_2)
    // pv
    val pvRdd = filterRdd.map{
      //  取出date、url
      case (date, url, guid) => (date, url)
    }
      // 先将每个元素去除首尾空格,然后只保留长度大于0的元素
      .filter(_._2.trim.length > 0)
      // 返回(date,1)的元组
      .map(tuple => (tuple._1, 1))
      // 按日期分组求和统计每天的pv数
      .reduceByKey(_ + _)
    println("====================pv output======================")
    // foreachPartition比foreach更优化
    pvRdd.foreachPartition(iter => iter.foreach(println))

    // uv
    // 先得到(date, guid)
    val uvRdd = filterRdd.map{case (date, url, guid) => (date, guid)}
      // 去重
        .distinct()
      // 先将元素去除首尾空格再保留长度大于0 的元素
        .filter(_._2.trim.length > 0)
      // 构造(date, 1)的元组
        .map(tuple => (tuple._1, 1))
      // 按date分组再根据value求和统计每天的uv数
        .reduceByKey(_ + _)
    println("======================uv output========================")
    uvRdd.foreachPartition(iter => iter.foreach(println))

    /**
      * union
      *   def union[T: ClassTag](first: RDD[T], rest: RDD[T]*)
      *   注意:union合并时要求两个rdd的类型必须一致
      */
    val unionRdd = pvRdd.union(uvRdd)
    unionRdd.foreach(println)
    /**
      * join
      *  def join[W](other: RDD[(K, W)], partitioner: Partitioner): RDD[(K, (V, W))]
      *  注意:join时要求所有的RDD必须为二元组类型的rdd
      *
      */
    val joinRdd = pvRdd.join(uvRdd)
    joinRdd.foreach{case (date, (pv, uv)) => println(s"${date}\t${pv}\t${uv}")}

    /**
      * 输出
      */
    // 合并后设置分区数为1
    joinRdd.coalesce(1).foreachPartition(iter => {
      // conn初始化为null
      var conn:Connection = null
      // 初始化ps_create为null
      var ps_create:PreparedStatement =null
      // 初始化ps_tru为null
      var ps_tru:PreparedStatement =null
      // 初始化ps_insert为null
      var ps_insert:PreparedStatement =null
      try{
        // 得到connection
        conn = ConnectionUtils.getConnection
        // 如果表不存在,则创建表
        val sql_create = "create table if not exists pvuv_tb (date varchar(66), pv int(10), uv int(10))"
        ps_create = conn.prepareStatement(sql_create)
        ps_create.execute()
        // 清空表格内容
        /*val sql_tru = "truncate pvuv_tb"
        ps_tru = conn.prepareStatement(sql_tru)
        ps_tru.execute()*/
        // 插入数据
        val sql_insert = "insert into pvuv_tb values (?, ?, ?)"
        ps_insert = conn.prepareStatement(sql_insert)
        iter.foreach{
          case (date, (pv, uv)) => println(s"${date}\t${pv}\t${uv}")
            ps_insert.setString(1, date) // 将date添加到第一个?
            ps_insert.setInt(2, uv) // 将pv添加到第二个?
            ps_insert.setInt(3, uv) // 将uv添加到第三个?
            ps_insert.executeUpdate() // 提交SQL语句
        }
      }catch{
        case e:Exception => println("MySQL Exception")
      }finally{
        // 关流
        if (ps_create != null) {
          ps_create.close()
        }
        if (ps_tru != null) {
          ps_tru.close()
        }
        if (ps_insert != null) {
          ps_insert.close()
        }
        ConnectionUtils.closeConnection(conn)
      }
    })

    // 关闭缓存
    filterRdd.unpersist()
    /**
      * 关闭资源
      */
    // 设置线程睡眠时间
    Thread.sleep(10000000000L)
    sc.stop()
  }
}


ConnectionUtils类

package com.fuyun.bigdate.spark

import java.io.InputStream
import java.sql.{Connection, DriverManager, PreparedStatement}
import java.util.Properties

/**
  * Created by lenovo on 2018/9/26.
  */
object ConnectionUtils {
  // 读取properties文件
  val inputStream:InputStream = ConnectionUtils.getClass.getClassLoader.getResourceAsStream("jdbc.properties")
  // 实例化properties对象
  val prop = new Properties()
  // 加载properties文件
  prop.load(inputStream)
  // 加载driver.class.name
  Class.forName(prop.getProperty("driver.class.name"))
  // 加载mysql.url
  val url = prop.getProperty("mysql.url")
  // 加载mysql.user
  val username = prop.getProperty("mysql.user")
  // 加载mysql.password
  val password = prop.getProperty("mysql.password")

  def getConnection:Connection = {
     DriverManager.getConnection(url, username, password)
  }
  def closeConnection(conn: Connection){
    if (conn != null) {
      conn.close()
    }
  }
}


jdbc.properties文件

此文件在main中的resources中创建,方便以后修改此文件而实现不同的需求

driver.class.name=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://192.168.xxx.xx:3306/spark_db
mysql.user=root
mysql.password=123456

在IDEA中打jar包的两种方式

IDEA打jar包

idea打包java可执行jar包

1,在项目上鼠标右键 --> Open Module Settings
在这里插入图片描述
2, Artifacts --> + --> JAR --> From modules with dependencies…
在这里插入图片描述
3, Main Class是你这个项目(脚本)的主方法,就是要运行的类,选一个
在这里插入图片描述
4,如下图,设置 META-INF/MANIFEST.MF
在这里插入图片描述
5,选中你这个项目的根目录,一定要放在根目录下
在这里插入图片描述
6,设置完是这样子的,关于 JAR files from libraries的两个选项:

选中第一个的话,打完包后是一个jar包

选中第二个的话,打完包后是一个jar包,外带你项目所用的jar包,个人推荐第二个
在这里插入图片描述
7,设置完后就可以点OK了

8,这个页面, Build on make打上勾,其他的不一样也没事
在这里插入图片描述

9,最后一步, Build Artifacts… --> XXX.jar --> Build
在这里插入图片描述
在这里插入图片描述

10,复制这里的路径去找jar包就行
在这里插入图片描述

IDEA中maven方式打jar包

  1. 先清除,在右侧的Maven Projects-> Lifecycle -> clean
    在这里插入图片描述
  2. 编译项目,菜单栏Build -> Make Project
    在这里插入图片描述
  3. 打jar包,在右侧的Maven Projects-> Lifecycle -> package
    在这里插入图片描述
  4. 然后到左侧项目的target中寻找jar包
    在这里插入图片描述

提交spark程序jar包运行

先将jar包放入linux的/opt/datas/目录

将mysql-connector-java-5.1.27-bin.jar放入/opt/cdh-5.7.6/spark-2.2.0-cdh5.7.6/jars/目录中

参数解释

--master 设置模式:本地、集群、yarn
--class  包含main方法的driver类的地址
--driver-memory  设置driver的内存
--executor-memory  设置executor的内存
--executor-cores  设置每个executor的核心数
--total-executor-cores  设置executor的总核心数
又上两个参数可以算出executor的个数total-executor-cores/executor-cores
--num-executors  设置executor的个数(只有在yarn上运行才有这个参数)

本地模式运行

bin/spark-submit
–master local[2]
–class com.fuyun.bigdate.spark.PvUvToMysql
–driver-memory 512M
–executor-memory 512M
–executor-cores 1
–total-executor-cores 2
/opt/datas/sparkLearning.jar
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

集群上运行

集群运行
bin/spark-submit
–master spark://192.168.xxx.xx:7077
–class com.fuyun.bigdate.spark.PvUvToMysql
–driver-memory 512M
–executor-memory 512M
–executor-cores 1
–total-executor-cores 2
/opt/datas/sparkLearning.jar
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

yarn上运行

yarn上运行
bin/spark-submit
–master yarn
–class com.fuyun.bigdate.spark.PvUvToMysql
–driver-memory 512M
–executor-memory 512M
–num-executors 2
/opt/datas/sparkLearning.jar
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值