文章目录
1. Structured Streaming介绍
spark进行实时数据流计算时有两个工具:Spark Streaming
和 Structured Streaming
。
Spark Streaming:编写RDD
代码处理数据流,可以解决非结构化的流式数据。
Structured Streaming:编写df
代码处理数据流,可以解决结构化和半结构化的流式数据。
Structured Streaming
是基于 Spark SQL 引擎构建的可扩展
和容错流处理引擎
,是在Spark 2.X
出来的流框架,采用了无界表(使用DataFrame)的概念,流数据相当于往一个表上不断追加行,数据会被转化为DataFrame和DataSets类型,可用采用SQL的方式操作结构化流数据。
1.1 实时计算和离线计算
1.1.1 实时计算
实时计算
,通常也称为“实时流计算”
、“流式计算”
流数据处理是指实时、连续地处理数据流。数据在被产生或接收后立即处理,并不需要等待所有数据到齐。数据的处理和传输是“逐条”进行的。
- 处理时间:由于数据被实时处理,系统响应时间非常短,通常在毫秒或者秒级。
- 数据量:流数据通常是无限的,数据持续不断地被生成和处理,系统需要持续运行。
1.1.2 离线计算
离线计算
,通常也称为“批处理”
,表示那些离线批量、延时较高的静态数据处理过程。
批数据处理是指在一个预定时间内收集一批数据,然后一次性对这批数据进行处理。数据是成批处理的,而不是逐条处理的。
- 处理时间:批处理通常不是实时的,处理的延迟可能是分钟、小时甚至更长,T+1.
- 数据量:批处理通常在所有数据收集完毕后进行,这意味着处理的数据集是固定大小的(如每日、每小时的数据)。数据处理完成后自动结束。
1.2 有界和无界数据
- 有界数据
有起始位置,有结束位置
。比如文件数据,有起始行,有结束行。有明确的数据容量大小
。处理数据时就能知道处理的数据大小。- 在处理数据时,按批次处理。
数据处理完程序就结束
。- 离线计算时处理的都是有界数据。
- 无界数据
有起始位置,没有结束位置
,知道数据的起始位置在哪里,但是数据的结束位置不知道(因为数据在不断产生,什么时候结束不知道)。- 流式数据都是无界数据。
- 无界数据的
总量是不确定的
,数据是不断产生的。 - 数据有时效性(有效期)。
- 处理无界数据时,
程序是持续运行的
。
2. 简单使用
- socket服务
- 安装ncat服务
- 在线安装
- yum install nc
- 离线安装
- rpm -ivh ncat-7.93-1.x86_64.rpm
- 在线安装
- 启动服务绑定9999端口
- ncat -lk 9999
- ncat -lk 9999
- 安装ncat服务
- Structured Streaming代码程序
- 使用的是SparkSQL,所以在进行代码编写时使用SparkSQL的方法进行编写。
- 使用 SparkSession
2,李四,22,男
3,王五,20,男
4,赵六,20,男
4,赵六,32,男
5,赵六,42,男
# 读取scoket产生的实时数据流
from pyspark.sql import SparkSession
ss = SparkSession.builder.getOrCreate()
#数据流读取使用readStream
opt = {
#指定读取socket服务的IP地址
'host':'192.168.88.100',
#指定读取端口
'port':9999
}
#使用socket方式读取网站服务的数据,得到一个无界的dataframe
df = ss.readStream.format('socket').options(**opt).load()
#实时输出数据
df.writeStream.start(format='console', outputMode='append').awaitTermination()
运行结果:
3. 编程模型
在进行流式数据开发,代码实现的过程
Structured Streaming在处理数据时分为四个部分
-
Input Table输入数据表 无界表 readStream
-
Qurey 对数据进行查询计算 DSL或SQL计算过程
-
Result Table 保存计算结果
-
Output 输出结果 writerStream
-
读取指定数据源的数据得到一个无界表数据
-
对无界表数据进行计算处理
-
接收无界表计算的结果
-
将接收到的结果进行输出
4. 数据处理流程
4.1 读取数据Source
支持读取的数据源
- 文件数据
- 从文件中读取数据
- kafka数据 常用
- 从kafka中读取数据
- socket数据
- 从网络端口读取数据
- Rate数据
- 框架自己产生数据,测试性能,优化参数
4.1.1 文件数据处理
option参数 | 描述说明 |
---|---|
maxFilesPerTrigger | 每个batch最多的文件数,默认是没有限制。比如我设置了这个值为1,那么同时增加了5个文件,这5个文件会每个文件作为一波数据,更新streaming dataframe。 |
latestFirst | 是否先处理最新的新文件, 当有大量文件积压时有用 (默认: false)。 |
fileNameOnly | 是否检查新文件只有文件名而不是完整路径(默认值:false) 将此设置为 true 时,以下文件将被视为同一个文件,因为它们的文件名“dataset.txt”相同: “file:///dataset.txt” “s3://a/数据集.txt " “s3n://a/b/dataset.txt” “s3a://a/b/c/dataset.txt”。 |
- 格式
spark.readStream.csv()
spark.readStream.load(format='csv',**options)
#流式读取文件数据
from pyspark.sql import SparkSession
ss = SparkSession.builder.getOrCreate()
# 读取文件数据
# 指定目录 不要指定文件名
# df = ss.readStream.load(format='csv',path='hdfs://node1:8020/data_stream',schema='id int,name string,gender string,age int,cls string')
# df = ss.readStream.csv(path='hdfs://node1:8020/data_stream',header=False,sep=',',schema='id int,name string,gender string,age int,cls string')
# df = ss.readStream.text(path='hdfs://node1:8020/data_stream2')
df = ss.readStream.option('maxFilesPerTrigger',1).csv('hdfs://node1:8020/data_csv',header=False,sep=',',schema='id int,name string,gender string,age int,cls string')
#输出
df.writeStream.start(format='console',outputMode='append').awaitTermination()
运行结果:
注意:
- 读取文件数据时,不能指定某个具体文件,而是指定文件所在的目录。
-
- 目录下的同一个文件只会被读取一次,处理过的文件数据不会再重新处理。
- 文件的读取方式在实际开发中用的比较少,生产一条数据,就要生成一个文件。但是,如果将多条数据收集之后写入统一文件,就变成了和批处理一样的开发。
- 实际开发中很少使用spark流读文件,可以使用flume工具流式读取文件,然后在通过spark读取产生flume。
4.2 计算操作 Operation
采用DSL的方式进行数据的计算
where 方法
groupby
orderby
#数据流的计算
from pyspark