所谓离线批处理,这里面有两个概念,一个是离线,还是一个是批处理。
先看批处理,说白了处理的是一批数据,只不过这里的一批,数据量往往相对比较大,比如100G,500G,1T等等;离线指的是,数据是静态,或者说数据不变。所以二者合一,所谓离线批处理,就是对静态的,不变的数据集进行处理。
有哪些特点呢?
所谓的实时流计算,是和离线批处理相对应的,所谓实时流,就是向水流一样,川流不息,不间断,实时的有数据产生。对这些数据的处理,就不能再像离线批处理那样?
有哪些特点?
项目模块的pom依赖,结构如下:
spark-parent.pom
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.desheng.bigdatagroupId>
<artifactId>spark-parentartifactId>
<version>1.0-SNAPSHOTversion>
<modules>
<module>spark-coremodule>
<module>spark-commonmodule>
<module>spark-sqlmodule>
<module>spark-streamingmodule>
modules>
<packaging>pompackaging>
<properties>
<spark.version>2.2.2spark.version>
<scala.version>2.11.8scala.version>
<hadoop.version>2.7.6hadoop.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-core_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-clientartifactId>
<version>${hadoop.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-sql_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-hive_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-streaming_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-streaming-kafka-0-8_2.11artifactId>
<version>${spark.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.scala-langgroupId>
<artifactId>scala-libraryartifactId>
<version>${scala.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.39version>
dependency>
dependencies>
project>
spark-streaming.pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>spark-parentartifactId>
<groupId>com.desheng.bigdatagroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>com.desheng.bigdatagroupId>
<artifactId>spark-streamingartifactId>
<version>1.0-SNAPSHOTversion>
<inceptionYear>2008inceptionYear>
<dependencies>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-streaming_2.11artifactId>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-streaming-kafka-0-8_2.11artifactId>
dependency>
dependencies>
<build>
<sourceDirectory>src/main/scalasourceDirectory>
<testSourceDirectory>src/test/scalatestSourceDirectory>
<plugins>
<plugin>
<groupId>org.scala-toolsgroupId>
<artifactId>maven-scala-pluginartifactId>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>testCompilegoal>
goals>
execution>
executions>
<configuration>
<scalaVersion>${scala.version}scalaVersion>
<args>
<arg>-target:jvm-1.5arg>
args>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-eclipse-pluginartifactId>
<configuration>
<downloadSources>truedownloadSources>
<buildcommands>
<buildcommand>ch.epfl.lamp.sdt.core.scalabuilderbuildcommand>
buildcommands>
<additionalProjectnatures>
<projectnature>ch.epfl.lamp.sdt.core.scalanatureprojectnature>
additionalProjectnatures>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINERclasspathContainer>
<classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINERclasspathContainer>
classpathContainers>
configuration>
plugin>
plugins>
build>
<reporting>
<plugins>
<plugin>
<groupId>org.scala-toolsgroupId>
<artifactId>maven-scala-pluginartifactId>
<configuration>
<scalaVersion>${scala.version}scalaVersion>
configuration>
plugin>
plugins>
reporting>
project>
/**
* SparkStreaming 基于网络端口产生实时数据,进行统计的入门案例
*
* SparkStreaming编程的入口类:StreamingContext
*/
object NetWorkStreamingOps {
def main(args: Array[String]): Unit = {
if(args == null || args.length < 3) {
println(
"""
|Parameter Errors! Usage: <batchInterval> <host> <port>
""".stripMargin)
System.exit(-1)
}
val Array(batchInterval, host, port) = args
val conf = new SparkConf()
.setAppName("NetWorkStreamingOps")
.setMaster("local[*]")
val ssc = new StreamingContext(conf, Seconds(batchInterval.toLong))
/*
接入外部网络产生的数据,转化成RDD--->DStream
摄入算子大多数都有持久化级别,大多数默认的级别就是StorageLevel.MEMORY_AND_DISK_SER_2
*/
val lines:ReceiverInputDStream[String] = ssc.socketTextStream(host, port.toInt)
val pairs:DStream[(String, Int)] = lines.flatMap(_.split("\\s+")).map((_, 1))
val ret = pairs.reduceByKey(_+_)
//打印结果到控制台
ret.print()
ssc.start()//开启一次流式计算
ssc.awaitTermination()
}
}
将上述案例中的master由local[*],改成了local,发现只能接收数据,无法处理数据。
上述警告说的是,在本地模式下面如果我们要使用receiver来接收外部数据的时候,必须要将local[N]中N>1。local[N],是给当前作业分配N个线程来进行计算。通过追踪源码,我们发现ssc.socketTextStream中开启了一个线程用来接收外部的数据,也就占用master中配置的线程资源,进而也就无法分配其他的计算资源给计算程序。
注意:如果我们的Streaming程序中,接收数据是基于这个Receiver的方式,必须要配置足够的线程来保证既有资源接收数据,又有资源计算数据,特别的在local模式下面,local[N]中的N>=2。
要想sparkstremaing程序连续不断的接收并处理外部数据,必须要执行start()和awaitTermination()。
同时,所有的处理的业务逻辑,都必须要在start()方法之前完成,不能在start()方法之后再写其他的业务逻辑。
我们在这个案例中,使用socketTextStream接收外部的数据,在这里其实使用了一个Receiver来接收数据的。
object HDFSStreamingOps {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("HDFSStreamingOps")
.setMaster("local")
val ssc = new StreamingContext(conf, Seconds(2))
// val lines:DStream[String] = ssc.textFileStream("file:///E:/data/input")
val lines:DStream[String] = ssc.textFileStream("hdfs://ns1/data/spark")
val ret = lines.flatMap(_.split("\\s+")).map((_, 1)).reduceByKey(_+_)
ret.print()
ssc.start()
ssc.awaitTermination()
}
}
说明:
1、如果加载的是本地目录,必须要通过流的方式写入
2、如果监听的是hdfs中的目录,该目录中的数据可以通过
hdfs dfs -put local-path hdfs-path
hdfs dfs -cp hdfs-src hdfs-dest
但是不可以通过hdfs dfs -mv hdfs-src hdfs-dest
当然我们也可以通过流的方式写入hdfs
3、只能监听目录中的新增文件,不可以监听文件中的新增数据