fileStream是Spark Streaming Basic Source的一种,用于“近实时”地分析HDFS(或者与HDFS API兼容的文件系统)指定目录(假设:dataDirectory)中新近写入的文件,dataDirectory中的文件需要满足以下约束条件:
(1)这些文件格式必须相同,如:统一为文本文件;
(2)这些文件在目录dataDirectory中的创建形式比较特殊:必须以原子方式被“移动”或“重命名”至目录dataDirectory中;
(3)一旦文件被“移动”或“重命名”至目录dataDirectory中,文件不可以被改变,例如:追加至这些文件的数据可能不会被处理。
之所以称之为“近实时”就是基于约束条件(2),文件的数据必须全部写入完成,并且被“移动”或“重命名”至目录dataDirectory中之后,这些文件才可以被处理。
调用示例如下:
directory:指定待分析文件的目录;
filter:用户指定的文件过滤器,用于过滤directory中的文件;
newFilesOnly:应用程序启动时,目录directory中可能已经存在一些文件,如果newFilesOnly值为true,表示忽略这些文件;如果newFilesOnly值为false,表示需要分析这些文件;
conf:用户指定的Hadoop相关的配置属性;
注:fileStream有另外两个重载方法,在此不再赘述。
如果分析的文件是文本文件,Spark提供了一个便利的方法:
fileStream的实现原理是比较简单的:以固定的时间间隔(duration)不断地探测目录(dataDirectory),每次探测时将时间段(now - duration, now]内新写入的文件(即文件的最近修改时间处于时间区间(now - duration, now])封装为RDD交由Spark处理。
Spark Streaming有一个核心组件:DStream,fileStream的实现依赖于其中的一个实现类:FileInputDStream。
而FileInputDStream的核心逻辑就是探测文件、封装RDD,由方法compute(重写至DStream compute)实现,
compute方法的注释引出了一个很重要的问题:我们为什么需要维护一个最近已分析文件的列表?
假设探测目录为dataDirectory,探测时间间隔为duration,当前时间为now,则本次选择的文件需要满足条件:文件的最近修改时间需要处于区间(now - duration, now],此时文件可能有以下几个状态:
(1)文件的最后修改时间小于或等于now - duration;
(2)文件的最后修改时间处于区间(now - duration, now);
(3)文件的最后修改时间等于now;
(4)文件的最后修改时间大于now;
考虑第(3)种情况,文件的最后修改时间等于now,它有可能在探测之前已被移动至目录dataDirectory,或者在探测时或探测完成之后被移动至目录dataDirectory;如果是后两者,就可能会出现文件“丢失”的情况(即文件不被处理),因为下次探测的时间点为now + duration,探测的时间范围为(now, now + duration],最近修改时间等于now的文件已不处于该区间。为了避免或减少文件“丢失”的情况,所以Spark Streaming fileStream允许将探测的时间范围向“前”扩展为(now - n * duration, now],如下所示:
ignore threshold:now - n * duration
current batch time:now
remember window:n * duration
也就是说,每一次探测时,我们会选择文件的最后修改时间处于区间(ignore threshold, current batch time]的文件,但其中有些文件可能在前几次的探测中已经被分析,为了防止出现重复分析的情况,我们需要记录时间区间(ignore threshold, current batch time](remember window)内已经被分析过的文件有哪些。
下面我们来分析compute的处理流程:
1. 寻找新的文件;
(1)计算ignore threshold;
这一步有两个重要的变量需要说明:initialModTimeIgnoreThreshold和durationToRemember。
initialModTimeIgnoreThreshold
它的值与newFilesOnly有关,newFilesOnly表示Spark Streaming App刚刚启动时是否分析目录dataDirectory中已有的文件:
newFilesOnly == true:不需要分析目录dataDirectory中已有的文件,因此initialModTimeIgnoreThreshold的值被设置为“当前时间”,表示仅仅分析最近修改时间大于“当前时间”的文件;
newFilesOnly == false:需要分析目录dataDirectory中已有的文件,因此initialModTimeIgnoreThreshold的值被设置为0(文件的最近修改时间必大于0)。
durationToRemember
slideDuration:表示探测的时间间隔。
minRememberDurationS:默认值为60s,可以通过属性spark.streaming.fileStream.minRememberDuration进行修改。
通过上面的代码可以看出,durationToRemember = slideDuration * math.ceil(minRememberDurationS.milliseconds.toDouble / batchDuration.milliseconds).toInt,durationToRemember就是我们前面提到的remember window,也就是说这个时间区间内的已分析文件会被记录。
ignore threshold取initialModTimeIgnoreThreshold、currentTime - durationToRemember.milliseconds的最大值,这也意味着即使newFilesOnly值为false,dataDirectory中的文件也不会被全部分析,只有最近修改时间大于currentTime - durationToRemember.milliseconds的文件才会被分析。
(2)创建过滤器实例;
过滤器实例实际就是Hadoop PathFilter实例,依赖于方法isNewFile构建,顾名思义这个过滤器实例是用来选取新文件的,新文件的标准需要满足以下四个条件:
a. 文件路径匹配用户指定的过滤器实例;
b. 文件的最近修改时间大于modTimeIgnoreThreshold;
c. 文件的最近修改时间小于或等于currentTime;
d. 文件尚没有被分析过,即文件没有出现在最近已分析文件的列表recentlySelectedFiles。
这里需要额外说明一下c,为什么文件的最近修改时间不能大于currentTime?这主要是为了防止Spark Streaming应用重启时出现文件被重复分析的情况。
假设应用的终止时间为time,重启时间为time + 5 * duration,recentlySelectedFiles仅保存最近一个duration已经被分析过的文件,即保存的时间窗口为duration;应用重启之后,第一次探测的时间为time + duration,如果允许文件的最近修改时间大于currentTime(即time + duration),则最近修改时间处于时间区间(time, +∞)的文件将全部被分析,这些文件被记入recentlySelectedFiles;第二次探测的时间为time + 2 * duration,因为recentlySelectedFiles的时间窗口为duration,此时可以认为它的值已经被清空,如果允许文件的最近修改时间大于currentTime(即time + 2 * duration),则最近修改时间处于时间区间(time + 2 * duration, +∞)的文件将全部被分析,这种情况下可以看出最近修改时间处于时间区间(time + 2 * duration, +∞)的文件被重复分析;此外探测时间为time + 3 * duration、time + 4 * duration、time + 5 * duration也将出现类似文件被重复分析的情况。综上所述,每次探测文件时,文件的最近修改时间不能大于currentTime。
(3)获取满足过滤器实例条件的文件路径;
至此,寻找“新”文件的流程结束。
2. 将找到的新文件加入已分析文件列表;
recentlySelectedFiles中的过期数据是由方法clearMetadata负责清理的。
3. 将找到的新文件封装为RDD;
(1)遍历新文件(路径),将每一个新文件(路径)通过SparkContext newAPIHadoopFile转换为一个RDD,最后形成一个RDD列表:fileRDDs;
(2)将fileRDDs转换为一个UnionRDD并返回;
至此,compute的整个处理流程结束。可以看出,整个流程中最为复杂的部分就是每次探测新文件的过程,特别是时间区间的选取以及最近已分析文件的缓存。
- 49、Spark Streaming基本工作原理
一.大数据实时计算介绍 1.概述 Spark Streaming,其实就是一种Spark提供的,对于大数据,进行实时计算的一种框架.它的底层,其实,也是基于我们之前讲解的Spark Core的. 基本 ...
- Spark Streaming简介及原理
简介: SparkStreaming是一套框架. SparkStreaming是Spark核心API的一个扩展,可以实现高吞吐量的,具备容错机制的实时流数据处理. 支持多种数据源获取数据: Spark ...
- 66、Spark Streaming:数据处理原理剖析与源码分析(block与batch关系透彻解析)
一.数据处理原理剖析 每隔我们设置的batch interval 的time,就去找ReceiverTracker,将其中的,从上次划分batch的时间,到目前为止的这个batch interval ...
- 63、Spark Streaming:架构原理深度剖析
一.架构原理深度剖析 StreamingContext初始化时,会创建一些内部的关键组件,DStreamGraph,ReceiverTracker,JobGenerator,JobScheduler, ...
- Spark Streaming初步使用以及工作原理详解
在大数据的各种框架中,hadoop无疑是大数据的主流,但是随着电商企业的发展,hadoop只适用于一些离线数据的处理,无法应对一些实时数据的处理分析,我们需要一些实时计算框架来分析数据.因此出现了很多 ...
- Spark Streaming的原理
Spark Streaming应用也是Spark应用,Spark Streaming生成的DStream最终也是会转化成RDD,然后进行RDD的计算,所以Spark Streaming最终的计算是RD ...
- Update(Stage4):Spark Streaming原理_运行过程_高级特性
Spark Streaming 导读 介绍 入门 原理 操作 Table of Contents 1. Spark Streaming 介绍 2. Spark Streaming 入门 2. 原理 3 ...
- spark streaming (二)
一.基础核心概念 1.StreamingContext详解 (一) 有两种创建StreamingContext的方式: val conf = new SparkConf().s ...
- Spark Streaming源码解读之数据清理内幕彻底解密
本期内容 : Spark Streaming数据清理原理和现象 Spark Streaming数据清理代码解析 Spark Streaming一直在运行的,在计算的过程中会不断的产生RDD ,如每秒钟 ...
随机推荐
- Asp.net简单三层+Sqllite 增删改查
新建项目à新建一个空白解决方案 在Model新建一个实体类 using System; using System.Collections.Generic; using System.Linq; usi ...
- The hacker's sanbox游戏
第一关:使用/usr/hashcat程序,对passwd中root的密码进行解密,得到gravity98 执行su,输入密码gravity98. 第二关:获取提供的工具,wget http://are ...
- [网络] C# NetHelper网络通信编程类教程与源码下载
点击下载 NetHelper.zip 主要功能如下所示 检查设置的IP地址是否正确,返回正确的IP地址 检查设置的端口号是否正确,返回正确的端口号 将字符串形式的IP地址转换成IPAddress对象 ...
- Android占位符
<xliff:g>标签介绍: 属性id可以随便命名 属性值举例说明%n$ms:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格 %n$md:代表输出的是整数,n代表 ...
- Ubuntu Server下建立VPN服务器 pptp 模式的方法
对于想要在外部访问内部的网络,除了在防火墙上开启相应服务器所对应的端口,最好的方法应该是建立VPN-Server,使得用户可以在外网任何一台计算机上拨入到内网中进行操作,而且VPN可以记录详细的日志, ...
- linux常用命令(自我积累)
创建目录:mkdir + 目录名 使文件可执行:chmod +x filename 执行文件:./filename 来执行您的脚本 {程序必须以下面的行开始(必须方在文件的第一行): #!/bin/s ...
- eclipse总是自动跳到ThreadPoolExecutor.java
解决方法:在eclipse中选择Window->Preference->Java->Debug, 将“Suspend execution on uncaught exceptions ...
- shell脚本学习之Bash shell 里各种括号的用法
今天在 SegmentFault 上看到又有人问起关于Shell里各种括号的问题.对于很多玩Shell的人,括号是个很尴尬的问题,用起来没问题,说起来不明白,我在这里总结一下Bash Shell几种括 ...
- Java设计模式(学习整理)---命令模式
设计模式之Command(学习整理) 1.Command定义 不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作. 将这些命令封装 ...
- vs2010 “发生生成错误,运行上次的成功运行的程序”怎么改回不运行。
当程序出现错误时,会出现下面对话框: 如果选择"是",并且勾选了"不再显示此对话框",对你以后的操作时非常麻烦的. 许多同学想再次调出次窗口,不知道怎么操作,操 ...