Structured Streaming

本文介绍了Apache Spark的Structured Streaming组件如何通过微批处理和ContinuousProcessing实现低延迟、弹性及end-to-end exactly once的流处理,重点讲解了其在数据源读取、数据转换、聚合和最终结果确保上的关键特性。

该组件进一步降低了处理数据的延迟时间, 它实现了"有且仅有一次(Exectly Once)" 语义, 可以保证数据被精准消费.

Structured Streaming 基于 Spark SQl 引擎, 是一个具有弹性和容错的流式处理引擎. 使用 Structure Streaming 处理流式计算的方式和使用批处理计算静态数据(表中的数据)的方式是一样的.

随着流数据的持续到达, Spark SQL 引擎持续不断的运行并得到最终的结果. 我们可以使用 Dataset/DataFrame API 来表达流的聚合, 事件-时间窗口(event-time windows), 流-批处理连接(stream-to-batch joins)等等. 这些计算都是运行在被优化过的 Spark SQL 引擎上. 最终, 通过 chekcpoin 和 WALs(Write-Ahead Logs), 系统保证end-to-end exactly-once.

总之, Structured Streaming 提供了快速, 弹性, 容错, end-to-end exactly-once 的流处理, 而用户不需要对流进行推理(比如 spark streaming 中的流的各种转换).

默认情况下, 在内部, Structured Streaming 查询使用微批处理引擎(micro-batch processing engine)处理, 微批处理引擎把流数据当做一系列的小批job(small batch jobs ) 来处理. 所以, 延迟低至 100 毫秒, 从 Spark2.3, 引入了一个新的低延迟处理模型:Continuous Processing, 延迟低至 1 毫秒.

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

object WordCount1 {
    def main(args: Array[String]): Unit = {
        // 1. 创建 SparkSession. 因为 ss 是基于 spark sql 引擎, 所以需要先创建 SparkSession
        val spark: SparkSession = SparkSession
            .builder()
            .master("local[*]")
            .appName("WordCount1")
            .getOrCreate()
        import spark.implicits._
        // 2. 从数据源(socket)中加载数据.
        val lines: DataFrame = spark.readStream
            .format("socket") // 设置数据源
            .option("host", "hadoop201")
            .option("port", 9999)
            .load

        // 3. 把每行数据切割成单词
        val words: Dataset[String] = lines.as[String].flatMap(_.split("\\W"))

        // 4. 计算 word count
        val wordCounts: DataFrame = words.groupBy("value").count()
        
        // 用sparksql计算
        lines.as[String].flatMap(_.split("\\w")).createOrReplaceTempView("w")
        val wordCount: sql.DataFrame = spark.sql(
        """
          |select 
          | *,
          | count(1) count
          |from w
          |group by count
          |""".stripMargin)
        
        // 5. 启动查询, 把结果打印到控制台
        val query: StreamingQuery = wordCounts.writeStream
            .outputMode("complete")
            .format("console")
            .start
        query.awaitTermination()

        spark.stop()
    }
}

. DataFrame lines 表示一个"无界表(unbounded table)", 存储着流中所有的文本数据. 这个无界表包含列名为value的一列数据, 数据的类型为String, 而且在流式文本数据中的每一行(line)就变成了无界表中的的一行(row). 注意, 这时我们仅仅设置了转换操作, 还没有启动它, 所以现在还没有收到任何数据
2. 紧接着我们把 DateFrame 通过 .as[String] 变成了 DataSet, 所以我们可以切割每行为多个单词.得到的 words DataSet包含了所有的单词.
3. 最后, 我们通过value(每个唯一的单词)进行分组得到wordCounts DataFrame, 并且统计每个单词的个数. 注意, wordCounts是一个流式DataFrame, 它表示流中正在运行的单词数(the running word counts of the stream).
4. 我们必须在流式数据(streaming data)上启动查询. 剩下的实际就是开始接收数据和计算个数. 为此, 当数据更新的时候, 我们通过outputMode("complete")来打印完整的计数集到控制台, 然后通过.start来启动流式计算.
5. 代码执行之后, 流式计算将会在后台启动. 查询对象(query: StreamingQuery)可以激活流式查询(streaming query), 然后通过awaitTermination()来等待查询的终止,从而阻止查询激活之后进程退出.

### Structured Streaming in Apache Spark: Introduction Apache Spark offers Structured Streaming as part of its comprehensive suite of big data processing capabilities[^1]. This feature allows developers to process streaming data using the same DataFrame or Dataset APIs used for batch processing. In essence, Structured Streaming treats streams like tables where rows continuously append over time. #### Key Features and Concepts - **Event Time Processing**: Supports event-time semantics which means operations can be based on timestamps within records rather than when they arrive at system boundaries. - **Fault Tolerance Guarantees**: Ensures exactly-once fault-tolerant end-to-end semantics by combining checkpointing and Write-Ahead Logs (WAL). - **Late Data Handling**: Provides mechanisms to handle late arriving events gracefully through watermark policies. ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("StructuredStreamingExample").getOrCreate() # Read from a source such as Kafka lines = spark.readStream.format("kafka") \ .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \ .option("subscribe", "topic_name") \ .load() ``` This code snippet demonstrates how one might begin setting up a simple stream reading operation with Kafka as input source. For those looking into deeper integration possibilities beyond basic setup: - Integration with other libraries becomes straightforward due to shared abstractions across different modules provided under Spark umbrella projects mentioned earlier. - Users have access not only to core functionalities but also specialized extensions tailored towards specific needs like machine learning pipelines via MLlib alongside real-time analytics tasks facilitated by this framework's design philosophy emphasizing ease-of-use without compromising power or flexibility.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值