Spark(RDD与DataFrame数据结构模型实战)

场景一:使用Spark RDD实现单词计数

代码如下:

package org.jy.data.yh.bigdata.drools.scala.sparkrdd

import org.apache.spark.SparkConf

import org.apache.spark.SparkContext

import org.apache.spark.rdd.RDD

/**

  * Spark RDD统计单词

  */

object SparkRDDWordCountFrep {

  def main(args: Array[String]): Unit = {

    // 创建SparkConf对象,存储应用程序的配置信息

    val conf = new SparkConf()

    // 设置应用程序名称,可以在Spark Web UI中显示的名称

    conf.setAppName("SparkRDD-WordCount")

    // 设置集群Master节点访问地址

    conf.setMaster("spark://centoshadoop1:7077")

    // 创建SparkContext对象,该对象是提交Spark应用程序的入口

    val sc = new SparkContext(conf);

    // 读取指定路径(取程序执行时传入的第一个参数)中的文件内容,生成一个RDD集合

    val linesRDD:RDD[String] = sc.textFile(args(0)); // 程序执行的第一个参数 args(0

    // 将RDD的每一个元素按照空格进行拆分并将结果合并为一个新的RDD

    val wordsRdd:RDD[String] = linesRDD.flatMap(_.split(" "))  // 空格进行拆分

    // 将RDD中的每个单词和数字1放到一个元组里,即(word,1)

    val paresRDD:RDD[(String,Int)] = wordsRdd.map((_,1))  // map操作

    // 对单词根据key进行聚合,对相同的key进行value的累加

    val wordCountsRDD:RDD[(String,Int)] = paresRDD.reduceByKey(_+_);

    // 按照单词数量降序排列

    val wordCountsSortRDD:RDD[(String,Int)] = wordCountsRDD.sortBy(_._2,false);

    // 保存结果到指定的路径(取程序执行时传入的第二个参数)

    wordCountsSortRDD.saveAsTextFile(args(1))

    // 停止SparkContext,结束该任务

    sc.stop();

  }

}

统计words.txt中单词的数量(mycluster为hadoop集群的逻辑名称)

bin/spark-submit \

--master spark://centoshadoop1:7077 \

--class org.jy.data.yh.bigdata.drools.scala.sparkrdd.SparkRDDWordCountFrep \

/home/hadoop/tools/SSO-Scala-SparkRdd-1.0-SNAPSHOT.jar \

hdfs://mycluster/input/words.txt \

hdfs://mycluster/output

查看统计的结果

hadoop fs -cat /output/*

(Bye,33)

(Hello,22)

(hadoop,22)

(yang,11)

(,11)

(bye,11)

(hong,11)

(world,11)

场景二:使用Spark SQL实现单词计数

代码如下

package org.jy.data.yh.bigdata.drools.scala.sparksql

import org.apache.spark.sql.{DataFrame, Dataset, SparkSession}

/**

 * Spark SQL统计单词计数WordCount,数据来源仍然是HDFS中的/input/words.txt

 */

object SparkSQLWordCountFrep {

      def main(args:Array[String]):Unit = {  // 定义main函数

          // 创建SparkSession对象,并设置应用名称,运行模式

        val session = SparkSession.builder()

            .appName("SparkSQLWordCountFrep") // 设置应用名称,在Spark Web UI界面中展示

            .master("spark://centoshadoop1:7077")  // spark的集群地址

              .getOrCreate()

        // 读取HDFS中的单词文件

        val lines : Dataset[String] = session.read.textFile("hdfs://mycluster/input/words.txt")

        // 导入session对象中的隐式转换

        import session.implicits._

        // 将Dataset中的数据安装空格进行切分并合并

        val words :Dataset[String] = lines.flatMap(_.split(" "))

        // 将Dataset中默认的列名value改为word,同时转换为DataFrame

        val df: DataFrame = words.withColumnRenamed("value","word")

        // 给DataFrame创建临时视图

        df.createTempView("v_words")

        // 执行SQL,从DataFrame中查询数据,按照单词进行分组

        val result:DataFrame = session.sql(

          "select word,count(*) as count from v_words group by word order by count desc"

        )

        // 显示查询结果

        result.show()

        // 关闭SparkSession

        session.close()

      }

}

bin/spark-submit --master spark://centoshadoop1:7077 \

--class org.jy.data.yh.bigdata.drools.scala.sparksql.SparkSQLWordCountFrep /home/hadoop/tools/SSO-Scala-SparkSql-1.0-SNAPSHOT.jar

执行结果如下:

+------+-----+

|  word|count|

+------+-----+

|   Bye|   33|

|hadoop|   23|

| Hello|   22|

|   bye|   14|

|      |   12|

| world|   12|

|  yang|   11|

|  hong|   11|

| hello|    1|

+------+-----+

场景三:使用Spark SQL读写MySQL数据库

代码如下:

package org.jy.data.yh.bigdata.drools.scala.sparksql

import org.apache.spark.sql.{Row, SparkSession}

import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}

/**

  * 将RDD的计算结果写入到关系数据库中,以便于前端页面展示

  * 本例使用Spark SQL将DataFrame中的数据通过JDBC写入到MySQL数据库中

  */

object SparkSQLJDBCToDBMysql {

      def main(args:Array[String]):Unit ={

           // 创建或者得到SparkSession

        val spark = SparkSession.builder()

          .appName("通过SparkJDBC把计算的结果写入MySQL")

          .getOrCreate()

        // 创建存放两条学生信息的RDD

        val studentRDD = spark.sparkContext.parallelize(

          Array("4 xiaoming 26","5 xiaogang 27")  // 各项间以空格分割

        ).map(_.split(" "))

        // 通过StructType指定每个字段的Schema

        val schema = StructType(

          List(  // 指定数据类型

            StructField("id",IntegerType,true),

            StructField("name",StringType,true),

            StructField("age",IntegerType,true)

          )

        )

        // 将studentRDD映射为rowRDD,rowRDD中的每一个元素都为一个Row对象

        val rowRDD = studentRDD.map(line=>

            Row(line(0).toInt,line(1).trim,line(2).toInt)

        )

        // 建立rowRDD和Schema之间的对应关系

        val studentDF = spark.createDataFrame(rowRDD,schema);

        // 将结果追加到MySQL的student表中

        studentDF.write.mode("append") // 保存模式为追加,即是在原来的表中追加数据

          .format("jdbc")

          .option("url","jdbc:mysql://192.168.227.136:3306/spark_db?createDatabaseIfNotExist=true&characterEncoding=UTF-8&useSSL=fals")

          .option("driver","com.mysql.jdbc.Driver")

          .option("dbtable","student") // 表名

          .option("user","root")

          .option("password","123456")

          .save()

      }

}

==============================================================================

create database spark_db;

mysql> use spark_db;

Database changed

mysql> create table student(id int,name varchar(20),age int);

Query OK, 0 rows affected (0.04 sec)

插入三条测试数据

insert into student values(1,'zhangsan',23);

insert into student values(2,'lisi',19);

insert into student values(3,'wangwu',25);

maven打包发布到Spark 集群

 bin/spark-submit \

 --master spark://centoshadoop1:7077  \

 --jars /home/hadoop/tools/mysql-connector-java-5.1.46.jar \

 --class org.jy.data.yh.bigdata.drools.scala.sparksql.SparkSQLJDBCToDBMysql \

/home/hadoop/tools/SSO-Scala-SparkSql-1.0-SNAPSHOT.jar

查看数据表student记录:

mysql> select * from student;

+------+----------+------+

| id   | name     | age  |

+------+----------+------+

|    1 | zhangsan |   23 |

|    2 | lisi     |   19 |

|    3 | wangwu   |   25 |

|    5 | xiaogang |   27 |

|    4 | xiaoming |   26 |

+------+----------+------+

5 rows in set (0.00 sec)

发布了74 篇原创文章 · 获赞 4 · 访问量 3192

猜你喜欢

转载自blog.csdn.net/u014635374/article/details/105433885