版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
传送门:大数据系列文章目录
官方网址:http://spark.apache.org/、 http://spark.apache.org/sql/
从Spark 2.0至Spark 2.4版本,目前支持数据源有4种,其中Kafka 数据源使用作为广泛,其他数据源主要用于开发测试程序。
文档: http://spark.apache.org/docs/2.4.5/structured-streaming-programming-guide.html#input-sources
DataStreamReader 接口
在Structured Streaming中使用SparkSession#readStream读取流式数据,返回DataStreamReader对象,指定读取数据源相关信息,声明如下:
查看DataStreamReader中方法可以发现与DataFrameReader中基本一致,编码上更加方便加载流式数据。
文件数据源
将目录中写入的文件作为数据流读取, 支持的文件格式为: text、 csv、 json、 orc、 parquet,可以设置相关可选参数:
从文件数据源加载数据伪代码如下:
val streamDF = spark
.readStream
// Schema must be specified when creating a streaming source DataFrame.
.schema(schema)
// 每个trigger最大文件数量
.option("maxFilesPerTrigger",100)
// 是否首先计算最新的文件,默认为false
.option("latestFirst",value = true)
// 是否只检查名字,如果名字相同,则不视为更新,默认为false
.option("fileNameOnly",value = true)
.csv("*.csv")
演示范例: 监听某一个目录,读取csv格式数据,统计年龄小于25岁的人群的爱好排行榜。
测试数据
jack;23;running
charles;32;basketball
tom;28;football
lili;24;running
bob;20;swimming
zhangsan;32;running
lisi;28;running
wangwu;24;running
zhaoliu;26;swimming
honghong;28;running
业务实现代码,监控Windows系统目录【D:/datas】
package file
import org.apache.spark.sql.streaming.{OutputMode, StreamingQuery}
import org.apache.spark.sql.types.{IntegerType, StringType, StructType}
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
/**
* 使用Structured Streaming从目录中读取文件数据:统计年龄小于25岁的人群的爱好排行榜
*/
object StructuredFileSource {
def main(args: Array[String]): Unit = {
// 构建SparkSession实例对象
val spark: SparkSession = SparkSession.builder()
.appName(this.getClass.getSimpleName.stripSuffix("$"))
.master("local[2]")
// 设置Shuffle分区数目
.config("spark.sql.shuffle.partitions", "2")
.getOrCreate()
// 导入隐式转换和函数库
import spark.implicits._
// TODO: 从文件系统,监控目录,读取CSV格式数据
// 数据样本 -> jack,23,running
val csvSchema: StructType = new StructType()
.add("name", StringType, nullable = true)
.add("age", IntegerType, nullable = true)
.add("hobby", StringType, nullable = true)
val inputStreamDF: DataFrame = spark.readStream
.option("sep", ";")
.option("header", "false")
// 指定schema信息
.schema(csvSchema)
.csv("file:///D:/datas/")
// 依据业务需求,分析数据:统计年龄小于25岁的人群的爱好排行榜
val resultStreamDF: Dataset[Row] = inputStreamDF
// 年龄小于25岁
.filter($"age" < 25)
// 按照爱好分组统计
.groupBy($"hobby").count()
// 按照词频降序排序
.orderBy($"count".desc)
// 设置Streaming应用输出及启动
val query: StreamingQuery = resultStreamDF.writeStream
// 对流式应用输出来说,设置输出模式
.outputMode(OutputMode.Complete())
.format("console")
.option("numRows", "10")
.option("truncate", "false")
// 流式应用,需要启动start
.start()
// 查询器等待流式应用终止
query.awaitTermination()
query.stop() // 等待所有任务运行完成才停止运行
}
}
执行结果: