(2)source和sink详解

(2)source和sink详解_第1张图片

前面第一小节也提到了,Structured Streaming会增量的从source中读取数据,映射成一张表,对该表进行增量的查询分析,然后组合中间状态,再把结果输出到结果表,然后刷到外部存储系统sink。

本小节主要是详细讲解source 和 sink。

1. source

目前支持的内置source有:

1) File Source

从给定的目录读取数据,目前支持的格式有text,csv,json,parquet。容错,文件必须原子操作的方式放置到指定的目录下,很多文件系统支持的move操作即可实现。

path:输入目录,对所有的文件格式通用。

maxFilesPerTrigger:每次触发读取文件的最大数。

latestFirst:是否先处理最新加入的文件,当有很多文件时,该参数有用(默认是false)。

fileNameOnly:检测新文件是否只根据文件名称,而不是整个文件路径,默认是false。假如,该值设置为true,那么下列文件会被认为是同一个文件:

"file:///dataset.txt"
"s3://a/dataset.txt"
"s3n://a/b/dataset.txt"
"s3a://a/b/c/dataset.txt"

2) Kafka Source:从kafka拉取数据。仅兼容kafka 0.10.0或者更高版本。容错。

3) Socket Source(for testing):

从一个连接中读取UTF8编码的文本数据。不容错。

该source的配置主要是两个host 去链接的目标主机; port 去连接的目标端口。

4) Rate Source(for testing

每秒钟产生给定行数的数据,每个输出包括一个时间戳 timestamp(Timestamp类型,代表消息分发的时间)和value(long类型,起始行是0)。该API用来测试的。

主要配置

rowsPerSecond (默认是1):每秒钟产生数据的行数。

rampUptime(默认是,0s,单位是秒,比如可以初始化为 5s):在生产速率达到rampUptime之前需要热身加速的时间。

numPartitions(),默认是spark的默认并行度。该值代表产生数据的分区数。

source将尽力达到rowsPerSecond,但查询可能受资源约束,并且可以调整numPartitions以帮助达到所需的速度。

2.output modes 

创建了source dataframe和组织了相关处理逻辑之后,就剩下以Dataset.writeStream的形式将数据写入到sink。下面,是一些常用的配置:

1). 输出sink 细节:数据格式,位置等。

2). 输出模式:指定输出到sink的内容。

A)Append mode(default):仅仅从上次触发计算到当前新增的行会被输出到sink。仅仅支持行数据插入结果表后不进行更改的query操作。因此,这种方式能保证每行数据仅仅输出一次。例如,带有Select,where,map,flatmap,filter,join等的query操作支持append模式。

B)Complete mode:每次trigger都会将整个结果表输出到sink。这个是针对聚合操作的。

C) Updata mode:仅仅是自上次trigger之后结果表有变更的行会输出到sink。在以后的版本中会有更详细的信息。

3). 查询名称:指定一个便于识别的查询名称。

4). 触发间隔:可选的指定触发间隔,如果没有指定,系统在之前的处理完之后,立即检查数据可用性。如果指定了时间间隔,由于处理时间导致下次出发延迟,那么结束后会立即触发处理。

5). Checkpoint位置对于一些支持端到端容错保证的sink,最好指定checkpoint信息。并且最好是hdfs 兼容的容错的文件系统。下面会详细讨论。

3.sinks

FileSink:保存数据到指定的目录

noAggDF
  .writeStream
  .format("parquet")
  .option("checkpointLocation", "path/to/checkpoint/dir")
  .option("path", "path/to/destination/dir")
  .start() 

Foreach sink:可以在输出的数据上做任何操作。

writeStream
  .foreach(...)
.start()

Console sink(for debugging):每次trigger都会将结果输出到console或stdout。

aggDF
  .writeStream
  .outputMode("complete")
  .format("console")
  .start()

memory sink输出以一个内存表的形式保存在内存中。Append和complete模式都支持。由于数据是保存在driver端的,所以该模式适合小数据量测试

// Have all the aggregates in an in-memory table
aggDF
  .writeStream
  .queryName("aggregates")    // this query name will be the table name
  .outputMode("complete")
  .format("memory")
  .start()
spark.sql("select * from aggregates").show()

 

kafkasink

支持stream和batch数据写入kafka

val ds = df
  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
  .writeStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
  .option("topic", "topic1")
  .start()

4.Sink支持的输出模式 

 

  1.  

Sink

Outputmode

Options

容错

注释

FileSink

Append

path:输出路径,必须指定

Yes, 仅一次处理

支持写入分区表。按照时间分区或许比较好使。

Kafkasink

Append,Update,complete

会有专题

YES。最少一次处理语义。

会有专题

ForeachSink

Append,Update,Complete

None

依赖于具体的ForeachWriter的实现

下面会有例子

ConsoleSink

Append,Complete,Update

NumRows:每个trigger显示的行数。Truncate:假如太长是否删除,默认是true

No

 

MemorySink

Append,Complete

None

No.但是在Completemode 重新query就会导致重新创建整张表

后续sql使用的表名就是queryName

要触发整个执行流程,必须调用start函数,该函数会返回一个StreamingQuery对象,该对象是正在运行的执行器的一个句柄。可以使用该对象来管理查询,后面详细介绍。

// ========== DF with no aggregations ==========
val noAggDF = deviceDataDf.select("device").where("signal > 10")   

// Print new data to console
noAggDF
  .writeStream
  .format("console")
  .start()

// Write new data to Parquet files
noAggDF
  .writeStream
  .format("parquet")
  .option("checkpointLocation", "path/to/checkpoint/dir")
  .option("path", "path/to/destination/dir")
  .start()

// ========== DF with aggregation ==========
val aggDF = df.groupBy("device").count()

// Print updated aggregations to console
aggDF
  .writeStream
  .outputMode("complete")
  .format("console")
  .start()

// Have all the aggregates in an in-memory table
aggDF
  .writeStream
  .queryName("aggregates")    // this query name will be the table name
  .outputMode("complete")
  .format("memory")
  .start()

spark.sql("select * from aggregates").show()   // interactively query in-memory table

 

你可能感兴趣的:((2)source和sink详解)