详解 Spark Streaming 的 DStream 对象

一、DStream 的创建

1. 通过 RDD 队列

DStream 在内部实现上是一系列连续的 RDD 来表示。每个 RDD 包含有采集周期内的数据

/**
基本语法:StreamingContext.queueStream(queueOfRDDs: Queue, oneAtATime = false)
*/
object DStreamFromRddQueue {
   
    def main(args: Array[String]): Unit = {
   
        val conf = new SparkConf().setMaster("local[*]").setAppName("ds")
        val ssc = new StreamingContext(conf, Seconds(3))
        
        val queueOfRdds = mutable.Queue[RDD[Int]]()
        
        val ds = ssc.queueStream(queueOfRdds, oneAtATime = false)
        ds.print()
        
        ssc.start()
        // 向 RDD 队列中添加元素
        for(i <- 1 to 5) {
   
            queueOfRdds += ssc.sparkContext.makeRDD(1 to 300, 10)
			Thread.sleep(2000)
        }
        
        ssc.awaitTermination()
    }
}

2. 通过自定义数据源

通过继承 Receiver 抽象类,并实现 onStart、onStop 方法来自定义数据源采集

/**
	实现步骤:
	1.继承 Receiver[T]() 抽象类,定义泛型,并传递参数
		1.1 泛型是采集的数据类型
		1.2 传递的参数是存储级别,StorageLevel 中的枚举值
	2.实现 onStart、onStop 方法
	3.使用 receiverStream(receiver) 创建 DStream
*/
object DStreamFromDiy {
   
    def main(args: Array[String]): Unit = {
   
        val conf = new SparkConf().setMaster("local[*]").setAppName("ds")
        val ssc = new StreamingContext(conf, Seconds(3))
        
        // 使用自定义数据源采集数据
        val ds: ReceiverInputDStream[String] = ssc.receiverStream(new MyReceiver())
        ds.print()
        
        ssc.start()
        ssc.awaitTermination()
    }
}

// 自定义数据源采集
class MyReceiver extends Receiver[String](StorageLevel.MEMORY_ONLY) {
   
    private val flag = true
    // 当 ssc.start() 调用后,启动一个独立的线程去采集数据
    override def onStart(): Unit = {
   
        new Thread(new Runnable(){
   
            override def run() {
   
                while(flag) {
   
                	val data = "数据为:" + new Random().nextInt(10)
                    // 将数据存储封装为 DStream
                    store(data)
                    
                    Thread.sleep(500)
                }
            }
        }, "receiver").start()
    }
    
    // 停止数据采集
    override def onStop(): Unit = {
   
        flag = false
    }
}

3. 通过 Kafka 数据源

3.1 版本选型
  • ReceiverAPI:需要一个专门的 Executor 去接收数据,然后发送给其他的 Executor 做计算。所以当接收数据的 Executor 和计算的 Executor 速度不同时,特别在接收数据的 Executor 速度大于计算的 Executor 速度时,会导致计算数据的节点内存溢出。(早期版本中提供此方式,当前版本不适用)
  • DirectAPI:是由计算的 Executor 来主动接收消费 Kafka 的数据,速度由自身控制
3.2 实现
  • 引入依赖

    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-streaming-kafka-0-10_2.12</artifactId>
        <version>3.0.0</version>
    </dependency>
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值