人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
Spark(SparkSql) 写数据到 MySQL中(Spark读取TCP socket/文件)
Spark Streaming 整合 Kafka(Spark读取Kafka)
Spark Streaming 开窗函数 reduceByKeyAndWindow
Spark Streaming 整合 Flume(Spark读取Flume)
Spark 实时处理 总文章
spark提交命令 spark-submit 的参数 executor-memory、executor-cores、num-executors、spark.default.parallelism分析
SparkSql将数据写入到MySQL中:利用sparksql将数据写入到mysql表中(本地运行)
1.通过IDEA编写SparkSql代码
package itcast.sql
import java.util.Properties
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, SaveMode, SparkSession}
// 创建case class样例类Student
case class Student(id:Int,name:String,age:Int)
//sparksql写入数据到mysql中
object SparkSqlToMysql
{
def main(args: Array[String]): Unit =
{
// 1、创建sparkSession对象
// 本地模式运行:SparkSession.builder().appName("SparkSqlToMysql").master("local[2]").getOrCreate()
// 集群模式运行:SparkSession.builder().appName("SparkSqlToMysql").getOrCreate()
val spark: SparkSession = SparkSession.builder().appName("SparkSqlToMysql").master("local[2]").getOrCreate()
// 通过sparkSession获取sparkContext
val sc: SparkContext = spark.sparkContext
sc.setLogLevel("WARN")//设置日志输出级别
// 2、通过sparkContext加载数据文件。此处输入读取源是person.txt。
val data: RDD[String] = sc.textFile(args(0))
// 3、切分每一行,每一行中的数据以空格切分,每一行数据便分别封装为每一个String[]数组
val arrRDD: RDD[Array[String]] = data.map(_.split(" "))
// 4、RDD关联case class样例类Student。map输出为每个Student对象。
// x(下标值):获取每一个String[]数组中下标值对应的元素值赋值到每个Student对象中。
val studentRDD: RDD[Student] = arrRDD.map(x => Student(x(0).toInt,x(1),x(2).toInt))
// 将RDD转换成DataFrame首先需要导入隐式转换
import spark.implicits._
// 5、将RDD转换成DataFrame:val DataFrame对象: DataFrame = RDD数据.toDF()
val studentDF: DataFrame = studentRDD.toDF()
// 6、将DataFrame注册成表:DataFrame对象.createOrReplaceTempView("表名")
studentDF.createOrReplaceTempView("student")
//打印dataframe中的结果数据
studentDF.show()
// 7、操作student表 ,按照年龄进行降序排列
val resultDF: DataFrame = spark.sql("select * from student order by age desc")
// 8、把结果保存在mysql表中
// 创建Properties对象,配置连接mysql的用户名和密码
val prop =new Properties()
prop.setProperty("user","root")
prop.setProperty("password","admin")
// 1.把dataframe中数据写出到MySQL数据表中时,可以配置插入mode:overwrite覆盖、append追加、ignore忽略、error默认表存在则报错
// 2.mode需要对应4个参数:
// overwrite:覆盖(它会帮你创建一个表,然后进行覆盖)
// append:追加(它会帮你创建一个表,然后把数据追加到表里面)
// ignore:忽略(它表示只要当前表存在,它就不会进行任何操作)
// ErrorIfExists:只要表存在就报错(默认选项)
// 3.不配置mode参数时,则默认使用ErrorIfExists(只要表存在就报错)
// 4.jdbc("jdbc:mysql://IP或主机名:3306/数据库名","表名",Properties属性)
// resultDF.write.mode(SaveMode.Overwrite).jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)
resultDF.write.jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)
spark.stop()
}
}
===========================================================
package cn.itcast.stream
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import java.util.Properties
import org.apache.spark.sql.{DataFrame, Dataset, SaveMode, SparkSession}
case class Person(id:Int, name:String, age:Int)
/*
* window:nc.exe -l -p 9999端号
* Linus:nc -lk 9999端号
* */
//todo:利用sparkStreaming接受socket数据,实现单词计数
object SparkStreamingSocket {
def main(args: Array[String]): Unit = {
// //第一种获取SparkContext的写法
// //1、创建sparkConf 设置master的地址local[N] ,n必须大于1,其中1个线程负责去接受数据,另一线程负责处理接受到的数据
// val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocket").setMaster("local[2]")
// // 2、创建sparkContext
// val sc = new SparkContext(sparkConf)
//第二种获取SparkContext的写法
// 1、构建sparkSession 指定appName和master的地址。设置master的地址local[N] ,n必须大于1,其中1个线程负责去接受数据,另一线程负责处理接受到的数据
val spark: SparkSession = SparkSession.builder().appName("SparkStreamingSocket").master("local[2]").getOrCreate()
// 2、从sparkSession获取sparkContext对象
val sc: SparkContext = spark.sparkContext
sc.setLogLevel("WARN") //日志级别为 警告
//3、创建streamingContext,需要sparkContext和以多久时间间隔为一个批次
val ssc = new StreamingContext(sc,Seconds(1))
//4、通过streaming接受socket数据
val stream: ReceiverInputDStream[String] = ssc.socketTextStream("NODE1",9999)
//5、切分每一行。
//流的扁平化,最终输出的数据类型为一维数组Array[String],被分割符分割出来的每个数据都仅存储到同一个一维数组中。
//并且还会以回车换行符作为默认的分隔符,即回车换行符前面的数据也会被自动进行分割后,同样存储到同一个一维数组中。
//val words: DStream[String] = stream.flatMap(_.split(" "))
//最终输出的数据类型为二维数组Array[Array[String]]。
//一行数据就为一个一维数组Array[String],多行数据就有多个一维数组,最终多个一维数组一起被封装到同一个一维数组中。
val words: DStream[Array[String]] = stream.map(_.split(" "))
//二维数组.foreachRD:对二维数组进行遍历,遍历出每个一维数组,即遍历出每行数据
words.foreachRDD(rdd=>
{
val x: Long = rdd.count() //判断每个一维数组中的元素数量,即获取一行数据中被空格分割出来的多个小字符串的数量
println(x)
if (x > 0)
{
//rdd.map:对每个一维数组进行,即遍历出“每行中被空格切割出来的”多个小字符串,并把一行信息封装为一个RDD[Person]对象
val personRDD: RDD[Person] = rdd.map(x => Person(x(0).toInt,x(1),x(2).toInt))
// 将personRDD 转化为 DataFrame,并且需要首先手动导入隐式转换
import spark.implicits._
//val DataFrame对象 = RDD数据.toDF() 或 RDD数据.toDF
val personDF: DataFrame = personRDD.toDF()
// -------------------DSL语法操作 --------------
//1、显示DataFrame的数据,默认显示20行。可以指定显示N行:show(N)
personDF.show()
//2、显示DataFrame的schema信息(表结构信息)
personDF.printSchema()
//3、显示DataFrame记录数
println(personDF.count())
// --------------------SQL操作风格 -----------
// 将DataFrame注册成表
personDF.createOrReplaceTempView("t_person")
// 传入sql语句,进行操作
spark.sql("select * from t_person").show()
val resultDF: DataFrame = spark.sql("select * from t_person")
val prop =new Properties()
prop.setProperty("user","root")
prop.setProperty("password","admin")
resultDF.write.mode(SaveMode.Append).jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)
}
})
// //6、每个单词记为1
// val wordAndOne: DStream[(String, Int)] = words.map((_,1))
// //7、相同单词出现的次数累加
// val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
// //8、打印
// result.print()
//9、开启流式计算
ssc.start()
//一直会阻塞,等待退出
ssc.awaitTermination()
}
}