Spark Streaming之基础知识
一、概叙
- Spark Streaming是spark的核心API的扩展,用于构建弹性、高吞吐量、容错的在线数据流的流式处理程序
- 数据源多种,可来自kafka、flume、HDFS等
- 数据输出到HDFS、数据库、可视化界面
- 处理的数据是一批,属于微批处理
- 批处理间隔是 Spark Streaming 的核心概念和关键参数,它决定了 Spark Streaming 提交作业的频率和数据处理的延迟,同时也影响着数据处理的吞吐量和性能
- 它提供了一个高级抽象DStream,表示一个连续的数据流
- DStream可以通过输入数据流或者是其他DStream来创建
- 在内部,DStream是由一个个RDD序列来表示
二、特点
- 优点:
- 易用性:通过一些高阶函数来构建应用
- 容错性
- 易整合性:易整合到spark体系中
- 缺点:相对于“一次处理一条数据”架构的系统来说,它的延迟相对会高一些
三、DStream的创建
-
RDD队列创建(queueStream关键字)
val conf = new SparkConf().setAppName("RDDQueueDemo").setMaster("local[*]") val scc = new StreamingContext(conf, Seconds(5)) val queue: mutable.Queue[RDD[Int]] = mutable.Queue[RDD[Int]]() val rddDS: InputDStream[Int] = scc.queueStream(queue, true)
-
自定义数据源(需要继承Receiver,并实现onStart、onStop方法来自定义数据源采集)
class MySource(host: String, port: Int) extends Receiver[String](StorageLevel.MEMORY_ONLY){ /* 接收器启动的时候调用该方法. This function must initialize all resources (threads, buffers, etc.) necessary for receiving data. 这个函数内部必须初始化一些读取数据必须的资源 该方法不能阻塞, 所以 读取数据要在一个新的线程中进行. */ override def onStart(): Unit = { // 启动一个新的线程来接收数据 new Thread("Socket Receiver"){ override def run(): Unit = { receive() } }.start() } // 此方法用来接收数据 def receive()={ val socket = new Socket(host, port) val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, StandardCharsets.UTF_8)) var line: String = null // 当 receiver没有关闭, 且reader读取到了数据则循环发送给spark while (!isStopped && (line = reader.readLine()) != null ){ // 发送给spark store(line) } // 循环结束, 则关闭资源 reader.close() socket.close() // 重启任务 restart("Trying to connect again") } override def onStop(): Unit = { } } //使用自定义数据源 object MySourceDemo { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("StreamingWordCount").setMaster("local[*]") // 1. 创建SparkStreaming的入口对象: StreamingContext 参数2: 表示事件间隔 val ssc = new StreamingContext(conf, Seconds(5)) // 2. 创建一个DStream val lines: ReceiverInputDStream[String] = ssc.receiverStream[String](new MySource("hadoop101", 9999)) // 3. 一个个的单词 val words: DStream[String] = lines.flatMap(_.split("""\s+""")) // 4. 单词形成元组 val wordAndOne: DStream[(String, Int)] = words.map((_, 1)) // 5. 统计单词的个数 val count: DStream[(String, Int)] = wordAndOne.reduceByKey(_ + _) //6. 显示 count.print //7. 启动流式任务开始计算 ssc.start() //8. 等待计算结束才退出主程序 ssc.awaitTermination() ssc.stop(false) } }
-
kafka数据源(包内提供的 KafkaUtils 对象可以在 StreamingContext和JavaStreamingContext中以你的 Kafka 消息创建出 DStream)(重要)
-
导入依赖
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming-kafka-0-8_2.11</artifactId> <version>2.1.1</version> </dependency>
-
高级API (没有缓存,每次只能消费kafka中最新产生的消息)
import kafka.serializer.StringDecoder import org.apache.kafka.clients.consumer.ConsumerCo
-