学习致谢
https://www.bilibili.com/video/BV1Xz4y1m7cv?p=46
需求:
对上述案例的结果数据输出到挫制台外的其他组件,如MySQL/HDFS注意:
foreachRDD函数属于将DStream中结果数据RDD输出的操作,类似transform函数,针对每批次RDD数据操作,但无返回值
DStream.print方法源码底层调用的也是foreachRDD
代码实现
package streaming
import java.sql.{Connection, DriverManager, PreparedStatement, Timestamp}
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}
/**
* Author itcast
* DESC 使用窗口计算:每隔5s(滑动间隔)计算最近10s(窗口长度)的数据
* 模拟百度热搜排行榜,每隔10s计算最近20s的热搜词
* 最后使用自定义输出将结果输出到控制台 /HDFS/MYSQL
*/
object WordCount06 {
def main(args: Array[String]): Unit = {
//TODO 0.准备环境
val conf:SparkConf=new SparkConf().setMaster("spark").setMaster("local[*]")
val sc: SparkContext=new SparkContext(conf)
sc.setLogLevel("WARN")
//the time interval at which streaming data will be dicided into batches
val ssc:StreamingContext= new StreamingContext(sc,Seconds(5))
//TODO 1.加载数据
val lines:ReceiverInputDStream[String]=ssc.socketTextStream("node1",9999)
//TODO 2.处理数据
val resuleDS:DStream[(String,Int)]=lines.flatMap(_.split(" "))
.map((_,1))
// 模拟百度热搜排行榜,每隔10s计算最近20s的热搜词
// xindowDuration:窗口长度/窗口大小,表示要计算最近多长时间的数据
// slideDuration:滑动间隔,表示每隔多长时间计算一次
.reduceByKeyAndWindow((a:Int,b:Int)=>a+b,Seconds(20),Seconds(10))
//注意DStream没有提供直接排序的方法,所以需要直接对底层的RDD进行操作
//DStream的transform方法表示对DStream底层的RDD进行操作并返回结果
val sortResultDS:DStream[(String, Int)]=resuleDS.transform(rdd=>{
val sortRDD:RDD[(String,Int)]=rdd.sortBy(_._2,false)
val top3:Array[(String,Int)]=sortRDD.take(3)
println("======top3======")
top3.foreach(println)
println("======top3======")
sortRDD
})
//TODO 3.输出结果
resuleDS.print()//默认的输出
//自定义输出
sortResultDS.foreachRDD((rdd,time)=>{
val milliseconds:Long=time.milliseconds
println("-----自定义输出------")
println("batchtime:"+milliseconds)
println("-----自定义输出------")
// 最后使用自定义输出将结果输出到控制台 /HDFS/MYSQL
//输出到控制台
rdd.foreach(println)
rdd.coalesce(1).saveAsTextFile("DATA/OUTPUT/RESULT-"+milliseconds)
//输出到MYSQL
rdd.foreachPartition(iter=>{
/**
* 建表语句
* CREATE TABLE `t_hotwords`(
* ` time` timestamp NOT NULL DEFAULT CURRENT_TIMESTANP ON UPDATE CURRENT_TIMESTAMP,
* `word` varchar(255) NOT NULL,
* ` count` int(11)DEFAULT NULL,
* PRIMARY KEY ( `time `, `word `)
* ENGINE=InnoDB DEFAULT CHARSET=utf8;
*/
//开启连接
val conn:Connection = DriverManager. getConnection("jdbc:mysq1;//localhost:3396/bigdata?characterEncoding-UT-8","root", " root")
val sql ="INSERT INTO 'T_HOTWORDS' ('time','word','count')VALUES(?,?,?);"
val ps:PreparedStatement=conn.prepareStatement(sql)
iter.foreach(t=>{
val word:String=t._1
val count:Int=t._2
ps.setTimestamp( 1,new Timestamp(time.milliseconds) )
ps.setString( 2,word)
ps.setInt(3,count)
ps.addBatch()
ps.executeBatch()
})
//关闭连接
if(conn!=null) conn.close()
if (ps !=null) ps.close()
})
})
//TODO 4.启动并等待结束
ssc.start()
ssc.awaitTermination()//注意:流式应用程序启动之后需要一直运行等待停止、等待到来
//TODO 5.关闭资源
ssc.stop(stopSparkContext = true,stopGracefully = true)//优雅关闭
/**微博热搜
一组数字速读六中全会精神 一组数字速读六中全会精神 一组数字速读六中全会精神 一组数字速读六中全会精神 一组数字速读六中全会精神
怀孕老师晕倒学生飞奔相救 怀孕老师晕倒学生飞奔相救 怀孕老师晕倒学生飞奔相救
肯德基回应驱逐要水要纸巾男子 肯德基回应驱逐要水要纸巾男子
把中国命运牢牢掌握在自己手中
宝宝洗护研究所
初恋这件小事原型结局是be
陶虹退出张庭夫妇传媒公司股东
十年前QQ空间动态有多羞耻
当微博遇见LPL 当微博遇见LPL
被易烊千玺抱着的小女孩长大了
*/
}
}
演示
(1)输入
(2)控制台
(3)输出到指定目录
(4)输出到mysql