Structured Streaming Programming[结构化流式编程]

Structured Streaming Programming[结构化流式编程]

概述

结构化流是基于Spark SQL引擎构建的可扩展和容错流处理引擎。您可以使用静态数据的批处理计算的方式进行流式计算。Spark SQL引擎将负责渐进和连续地运行它,并在流数据继续到达时更新最终结果。您可以在Scala,Java或Python中使用Dataset / DataFrame API来进行流聚合、事件窗口、流式批处理等操作,这些计算操作均在同一个优化的Spark SQL引擎上执行。最后,系统通过检查点和写入日志确保端到端的一次性容错保证。简而言之,结构化流提供快速、可扩展、容错、端到端的精确一次流处理,而无需用户对流进行推理。

Spark 2.0是结构化流的ALPHA RELEASE,API仍然是实验性的。在本指南中,我们将向您介绍编程模型和API。首先,让我们从一个简单的例子开始 - 一个流单词计数。

简单示例

import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.sql.*;
import org.apache.spark.sql.streaming.StreamingQuery;

import java.util.Arrays;
import java.util.Iterator;

SparkSession spark = SparkSession
    .builder()
    .appName("JavaStructuredNetworkWordCount")
    .getOrCreate();

接下来,让我们创建一个流DataFrame,表示从监听localhost:9999的服务器接收的文本数据,并转换DataFrame以计算字数。

// Create DataFrame representing the stream of input lines from connection to localhost:9999
Dataset<String> lines = spark
  .readStream()
  .format("socket")
  .option("host", "localhost")
  .option("port", 9999)
  .load();

// Split the lines into words
Dataset<String> words = lines
    .as(Encoders.STRING())
    .flatMap(
        new FlatMapFunction<String, String>() {
          @Override
          public Iterator<String> call(String x) {
            return Arrays.asList(x.split(" ")).iterator();
          }
        }, Encoders.STRING());

// Generate running word count
Dataset<Row> wordCounts = words.groupBy("value").count();

这行DataFrame表示包含流文本数据的无界表。此表包含名为”value”的一列字符串,流文本数据中的每一行都变为表中的一行。注意,这不是当前接收任何数据,因为我们只是设置转换,还没有启动它。接下来,我们使用.as(Encoders.STRING())将DataFrame转换为String的数据集,以便我们可以应用flatMap操作将每行划分为多个单词。结果词Dataset包含所有词。最后,我们通过数据集中的唯一值进行分组并对它们进行计数,从而定义了wordCounts DataFrame。注意,这是一个流数据帧,它表示流的运行字计数。

我们现在已经设置了对流数据的查询。剩下的只是实际开始接收数据和计算计数。为此,我们将其设置为在每次更新时将一组完整的计数(由outputMode(“complete”)指定)打印到控制台。然后使用start()启动流计算。

// Start running the query that prints the running counts to the console
StreamingQuery query = wordCounts.writeStream()
  .outputMode("complete")
  .format("console")
  .start();

query.awaitTermination();

执行此代码后,流计算将在后台启动。 查询对象是活动流查询的句柄,我们决定等待查询的终止,使用query.awaitTermination()来阻止进程退出,而查询处于活动状态。

要实际执行此示例代码,您可以在自己的Spark应用程序中编译代码,或者只要在下载Spark后运行示例。 我们显示后者。 您将首先需要运行Netcat(在大多数类Unix系统中找到的小实用程序)作为数据服务器

$ nc -lk 9999

然后,在另一个终端中,您可以使用启动示例

$ ./bin/run-example org.apache.spark.examples.sql.streaming.JavaStructuredNetworkWordCount localhost 9999

然后,在运行netcat服务器的终端中键入的任何行将被计数并每秒在屏幕上打印。

# TERMINAL 1:
#Running Netcat
$ nc -lk 9999
apache spark
apache hadoop`
...
# TERMINAL 2: RUNNING JavaStructuredNetworkWordCount

$ ./bin/run-example org.apache.spark.examples.sql.streaming.JavaStructuredNetworkWordCount localhost 9999

-------------------------------------------
Batch: 0
-------------------------------------------
+------+-----+
| value|count|
+------+-----+
|apache|    1|
| spark|    1|
+------+-----+

-------------------------------------------
Batch: 1
-------------------------------------------
+------+-----+
| value|count|
+------+-----+
|apache|    2|
| spark|    1|
|hadoop|    1|
+------+-----+
...

编程模型

结构化流的关键思想是将实时数据流视为一个连续附加的表。这种新的流处理模型与批处理模型非常相似。您将在静态表上以流计算作为标准批处理查询,Spark将其作为无界输入表上的增量查询运行,以便我们更详细地了解这个模型。

基本概念

将输入数据流视为”输入表”, 到达流上的每个数据项都像添加到输入表的新行。
structured-streaming-stream-as-a-table
对输入的查询将生成”结果表”,每个触发间隔(例如,每1秒),新行将附加到输入表,最终更新结果表。 无论何时更新结果表,我们都希望将更改的结果行写入外部接收器。
structured-streaming-model
“输出”定义为写入外部存储器的内容。输出可以在不同模式下定义:

  • 完成模式 - 整个更新的结果表将被写入外部存储器。它是由存储连接器决定如何处理整个表的写入。
  • 附加模式 - 只有自上次触发后在结果表中附加的新行将被写入外部存储器。这仅适用于结果表中的现有行不会更改的查询。
  • 更新模式 - 只有自上次触发后在结果表中更新的行将被写入外部存储器(在Spark 2.0中尚不可用)。请注意,这不同于完整模式,因为此模式不输出未更改的行。

请注意,每种模式适用于某些类型的查询。 这将在后面详细讨论。

为了说明这个模型的使用,让我们在上面的简单示例的上下文中理解模型。第一行DataFrame是输入表,最后的wordCounts DataFrame是结果表。请注意,在流线上DataFrame生成wordCounts的查询与静态DataFrame完全相同。但是,当此查询启动时,Spark将不断地从套接字连接中检查新数据。如果有新数据,Spark将运行一个“增量”查询,将以前运行的计数与新数据组合,以计算更新的计数,如下所示。
structured-streaming-example-model
这个模型与许多其他流处理引擎显着不同。许多流传输系统需要用户自己维护运行的聚合,因此必须推理容错和数据一致性(至少一次,或最多一次或完全一次)。在这个模型中,Spark有负责在有新数据时更新结果表,从而减轻用户对它的推理。 作为示例,让我们看看这个模型如何处理基于事件时间的处理和晚到达的数据。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值