public class WordCountOnline {
public static void main(String[] args) {
/**
* 第一步,配置SparkConf
* 1.至少两条线程:因为SparkStreaming应用程序在运行的时候至少有一条线程用于不断的循环接收
* 数据,并且至少有一条线程用于处理接收的数据(否则的话无法有线程用于处理数据,随着时间的推移,内存和磁盘都会
* 不堪重负)
* 2.对集群而言,每个Executor肯定不止一个线程,那么对于spark Streaming的应用程序而言,
* Executor一般分配多少cores合适?一般而言,5个左右的core最佳
*/
SparkConf conf=new SparkConf().setAppName("wordcount");
/**
* 第二步:创建SparkStreamingContext
1.这是SparkStreaming应用程序所有功能的起始点和程序调度的核心
* SparkStreaming框架是基于时间的,和处理什么内容没有任何的关系
* SparkStreamingContext 的构建可以基于SparkConf 参数,也可以基于持久化的SparkStreamingContext
* 的内容恢复过来(典型的场景是Driver奔溃后重新启动,由于SparkStreaming是7*24小时不间断运行的,所以需要在Driver
* 重新启动后继续上一次的状态,此时的状态恢复需要基于曾经的CheckPoint)
* 2.在一个SparkStreaming应用程序中可以创建若干个SparkStreamingContext对象,Spark对象不能有
* 多个SparkContext对象
* 使用下一个SparkStreaming
* 之前需要把前面正在运行的SparkStreamingContext对象关闭掉,由此,我们得出,spark core
* 不关心SparkStreamingContext,它只是Sparkcore上的一个应用程序而已,只不过SparkStreaming框架要运行的话,
* 需要写逻辑代码
*/
JavaStreamingContext jsc = new JavaStreamingContext(conf,Durations.seconds(5));
/**
* 第三步:创建Spark Streaming输入数据来源inputStream
* 1.数据输入来源可以基于file,hdfs,Kafka
* 2.在这里我们指定数据来源于网络Socke端口,SparkStreaming连接上该端口,并在运行时一直监听
* 该端口的数据,当然该端口服务必须存在,并且在后续业务需要不断的有数据产生
* 3.如果经常在每间隔5秒钟没有数据的话不断地启动空的job其实会造成调度资源的浪费,因为 并没有数据需要发生计算
* 所以每次计算提交job前会判断是否有数据,如果没有的话,不再提交job
*/
JavaReceiverInputDStream<String> lines = jsc.socketTextStream("192.168.100.10", 9999);
/**
* 接下来就像对于RDD编程一样基于Dstream进行编程,在SparkStreaming具体发生计算前,其实质是把每个
* Batch的Dstream的操作翻译成对RDD的操作
*/
/**
* 对Dstream进行Transformation级别的处理,例如map,filter等高阶函数的编程
* 将每一行的字符串拆成单个的单词
*/
JavaDStream<String> words=lines.flatMap(new FlatMapFunction<String, String>() {
public Iterable<String> call(String line) throws Exception {
return Arrays.asList(line.split(" "));
}
});
/**
* 在单词拆分的基础上对每个单词进行实例计数为1
*/
JavaPairDStream<String, Integer> pairs=words.mapToPair(new PairFunction<String, String, Integer>() {
public Tuple2<String, Integer> call(String word) throws Exception {
// TODO Auto-generated method stub
return new Tuple2<String, Integer>(word, 1);
}
});
/**
* 在每个单词实例计数为1的基础上统计每个单词在文件中出现的总次数
*/
JavaPairDStream<String, Integer> wordCount=pairs.reduceByKey(new Function2<Integer, Integer, Integer>() {
public Integer call(Integer v1, Integer v2) throws Exception {
// TODO Auto-generated method stub
return v1+v2;
}
});
/**
* 此处的print并不会直接触发Job的支持,因为现在的一切都是在SparkStreaming的框架
* 控制之下,对于SparkStreaming而言是否触发真正的Job运行时基于Duration的时间间隔的
* SparkStreaming应用程序要想执行具体的job,对Dstream必须要有outputStream
* 操作,outputStream有很多类型的函数触发,print,saveAsTextFile
* 最重要的一个方法是ForeachRDD,因为SparkStreaming处理的结果一般都会放在
* Redis,数据库,DashBoard等上 面,而foreach就是用来完成这些功能的,
*/
wordCount.print();
/**
* SparkStreaming执行引擎也就是Driver开始运行
* Driver启动运行的时候是位于一条新的线程中的
* 当然其内部有消息循环体用于接受应用程序本身或者Executor中的消息
* 启动框架
*/
jsc.start();
jsc.awaitTermination();
jsc.close();
}
}
下面用scala实现
object WordCount {
def main(args: Array[String]) {
val conf=new SparkConf().setAppName("mastre")
val ssc=new StreamingContext(conf,Durations.seconds(1))
val lines=ssc.socketTextStream("192.168.100.10",9999)
val test=lines.flatMap(line=>line.split(" ")).map(word=>(word,1)).reduceByKey(_+_).print()
ssc.start()
ssc.awaitTermination()
ssc.stop()
}
}