环境
  虚拟机:VMware 10
  Linux版本:CentOS-6.5-x86_64
  客户端:Xshell4
  FTP:Xftp4
  jdk1.8
  scala-2.10.4(依赖jdk1.8)
  spark-1.6

一、receiver模式


1、receiver模式理解
在SparkStreaming程序运行起来后,Executor中会有receiver tasks接收kafka推送过来的数据。数据会被持久化,默认级别为MEMORY_AND_DISK_SER_2,这个级别也可以修改。receiver task对接收过来的数据进行存储和备份,这个过程会有节点之间的数据传输。备份完成后去zookeeper中更新消费偏移量,然后向Driver中的receiver tracker汇报数据的位置。最后Driver根据数据本地化将task分发到不同节点上执行。

2、receiver模式中存在的问题
当Driver进程挂掉后,Driver下的Executor都会被杀掉,当更新完zookeeper消费偏移量的时候,Driver如果挂掉了,就会存在找不到数据的问题,相当于丢失数据。
如何解决这个问题?
开启WAL(write ahead log)预写日志机制,在接受过来数据备份到其他节点的时候,同时备份到HDFS上一份(我们需要将接收来的数据的持久化级别降级到MEMORY_AND_DISK),这样就能保证数据的安全性。不过,因为写HDFS比较消耗性能,要在备份完数据之后才能进行更新zookeeper以及汇报位置等,这样会增加job的执行时间,这样对于任务的执行提高了延迟度。

3、receiver模式代码

  1. package com.wjy.ss;
  2.  
  3. import java.util.Arrays;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6.  
  7. import org.apache.spark.SparkConf;
  8. import org.apache.spark.api.java.function.FlatMapFunction;
  9. import org.apache.spark.api.java.function.Function2;
  10. import org.apache.spark.api.java.function.PairFunction;
  11. import org.apache.spark.storage.StorageLevel;
  12. import org.apache.spark.streaming.Durations;
  13. import org.apache.spark.streaming.api.java.JavaPairDStream;
  14. import org.apache.spark.streaming.api.java.JavaPairReceiverInputDStream;
  15. import org.apache.spark.streaming.api.java.JavaStreamingContext;
  16. import org.apache.spark.streaming.kafka.KafkaUtils;
  17.  
  18. import scala.Tuple2;
  19.  
  20. public class SparkStreamingOnKafkaReceiver {
  21.  
  22. public static void main(String[] args) {
  23. SparkConf conf = new SparkConf().setAppName("SparkStreamingOnKafkaReceiver").setMaster("local[2]");
  24. //开启预写日志 WAL机制
  25. conf.set("spark.streaming.receiver.writeAheadLog.enable", "true");
  26. JavaStreamingContext jsc = new JavaStreamingContext(conf,Durations.seconds(5));
  27. //可以保存接收的数据
  28. jsc.checkpoint("./receivedata");
  29.  
  30. /**
  31. * 设置读取的topic和接受数据的线程数
  32. */
  33. Map<String, Integer> topicConsumerConcurrency = new HashMap<String, Integer>();
  34. topicConsumerConcurrency.put("MYTOPIC", 1);
  35.  
  36. /**
  37. * 第一个参数是StreamingContext
  38. * 第二个参数是ZooKeeper集群信息(接受Kafka数据的时候会从Zookeeper中获得Offset等元数据信息)
  39. * 第三个参数是Consumer Group 消费者组
  40. * 第四个参数是消费的Topic以及并发读取Topic中Partition的线程数
  41. * 第五个参数设置receiver的存储级别 开启WAL机制 接收的数据存储级别要降级
  42. * 注意:
  43. * KafkaUtils.createStream 使用五个参数的方法,设置receiver的存储级别
  44. */
  45. JavaPairReceiverInputDStream<String, String> receiverDStream = KafkaUtils.createStream(jsc,
  46. "node3:2181,node4:2181,node5:2181",
  47. "MyFirstConsumerGroup",
  48. topicConsumerConcurrency,
  49. StorageLevel.MEMORY_AND_DISK());
  50.  
  51. receiverDStream.flatMap(new FlatMapFunction<Tuple2<String,String>, String>() {
  52. private static final long serialVersionUID = 1L;
  53.  
  54. @Override
  55. public Iterable<String> call(Tuple2<String, String> tuple)
  56. throws Exception {
  57. return Arrays.asList(tuple._2.split("\t"));
  58. }
  59. }).mapToPair(new PairFunction<String, String, Integer>() {
  60. private static final long serialVersionUID = 1L;
  61.  
  62. @Override
  63. public Tuple2<String, Integer> call(String word) throws Exception {
  64. return new Tuple2<String, Integer>(word,1);
  65. }
  66. }).reduceByKey(new Function2<Integer, Integer, Integer>() {
  67. private static final long serialVersionUID = 1L;
  68. @Override
  69. public Integer call(Integer v1, Integer v2) throws Exception {
  70. return v1+v2;
  71. }
  72. }).print(100);
  73.  
  74. jsc.start();
  75. jsc.awaitTermination();
  76. jsc.close();
  77. }
  78.  
  79. }

4、receiver的并行度设置
receiver的并行度是由spark.streaming.blockInterval来决定的,默认为200ms,假设batchInterval为5s,那么每隔blockInterval就会产生一个block,这里就对应每批次产生RDD的partition,这样5秒产生的这个Dstream中的这个RDD的partition为25个,并行度就是25。如果想提高并行度可以减少blockInterval的数值,但是最好不要低于50ms。


由于receiver模式存在的问题,目前这种模式在实际生产中用的较少。

二、Driect模式

1、Direct模式理解
SparkStreaming+kafka 的Driect模式就是将kafka看成存数据的一方,不是被动接收数据,而是主动去取数据。消费者偏移量也不是用zookeeper来管理,而是SparkStreaming内部对消费者偏移量自动来维护,默认消费偏移量是在内存中,当然如果设置了checkpoint目录,那么消费偏移量也会保存在checkpoint中。当然也可以实现用zookeeper来管理。

2、Direct模式并行度设置
Direct模式的并行度是由读取的kafka中topic的partition数决定的。

3、Direct模式代码

  1. package com.wjy.ss;
  2.  
  3. import java.util.Arrays;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.Map;
  7.  
  8. import kafka.serializer.StringDecoder;
  9.  
  10. import org.apache.spark.SparkConf;
  11. import org.apache.spark.api.java.function.FlatMapFunction;
  12. import org.apache.spark.api.java.function.Function2;
  13. import org.apache.spark.api.java.function.PairFunction;
  14. import org.apache.spark.streaming.Durations;
  15. import org.apache.spark.streaming.api.java.JavaPairInputDStream;
  16. import org.apache.spark.streaming.api.java.JavaStreamingContext;
  17. import org.apache.spark.streaming.kafka.KafkaUtils;
  18.  
  19. import scala.Tuple2;
  20.  
  21. public class SparkStreamingOnKafkaDirected {
  22.  
  23. public static void main(String[] args) {
  24. SparkConf conf = new SparkConf().setMaster("local").setAppName("SparkStreamingOnKafkaDirected");
  25. conf.set("spark.streaming.backpressure.enabled", "false");
  26. conf.set("spark.streaming.kafka.maxRatePerPartition ", "100");
  27. JavaStreamingContext jsc = new JavaStreamingContext(conf, Durations.seconds(5));
  28. /**
  29. * 可以不设置checkpoint 不设置不保存offset,offset默认在内存中有一份,如果设置checkpoint在checkpoint也有一份offset, 一般要设置。
  30. */
  31. jsc.checkpoint("./checkpoint");
  32. Map<String, String> kafkaParameters = new HashMap<String, String>();
  33. kafkaParameters.put("metadata.broker.list", "node1:9092,node2:9092,node3:9092");
  34. kafkaParameters.put("auto.offset.reset", "smallest");
  35. HashSet<String> topics = new HashSet<String>();
  36. topics.add("Mytopic");
  37.  
  38. JavaPairInputDStream<String, String> lines =
  39. KafkaUtils.createDirectStream(jsc,
  40. String.class,
  41. String.class,
  42. StringDecoder.class,
  43. StringDecoder.class,
  44. kafkaParameters,
  45. topics);
  46.  
  47. lines.flatMap(new FlatMapFunction<Tuple2<String,String>, String>() {
  48. //如果是Scala,由于SAM转换,所以可以写成val words = lines.flatMap { line => line.split(" ")}
  49. private static final long serialVersionUID = 1L;
  50.  
  51. public Iterable<String> call(Tuple2<String,String> tuple) throws Exception {
  52. return Arrays.asList(tuple._2.split("\t"));
  53. }
  54. }).mapToPair(new PairFunction<String, String, Integer>() {
  55. private static final long serialVersionUID = 1L;
  56.  
  57. public Tuple2<String, Integer> call(String word) throws Exception {
  58. return new Tuple2<String, Integer>(word, 1);
  59. }
  60. }).reduceByKey(new Function2<Integer, Integer, Integer>() { //对相同的Key,进行Value的累计(包括Local和Reducer级别同时Reduce)
  61. private static final long serialVersionUID = 1L;
  62. public Integer call(Integer v1, Integer v2) throws Exception {
  63. return v1 + v2;
  64. }
  65. }).print();
  66.  
  67. jsc.start();
  68. jsc.awaitTermination();
  69. jsc.close();
  70.  
  71. }
  72.  
  73. }

三、相关配置
1、反压机制:
spark.streaming.backpressure.enabled 默认false

2、blockInterval:
spark.streaming.blockInterval 默认200ms

3、接收数据速率:
spark.streaming.receiver.maxRate 默认没有设置

4、预写日志:
spark.streaming.receiver.writeAheadLog.enable 默认false没有开启

5、该参数决定是否需要以Gracefully方式来关闭Streaming程序(详情请参见SPARK-7776)。Spark会在启动 StreamingContext 的时候注册这个钩子
spark.streaming.stopGracefullyOnShutdown

6、每个分区每秒钟接收的消息数量
spark.streaming.kafka.maxRatePerPartition

参考:
Spark

【SparkStreaming学习之三】 SparkStreaming和kafka整合的更多相关文章

  1. WebService学习之三:spring+cxf整合

    步骤一:spring项目(java web项目)引入CXF jar包 步骤二:创建webservice服务器 1)创建一个服务接口 package com.buss.app.login; import ...

  2. 【Spring Boot学习之三】Spring Boot整合数据源

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.Spring Boot整合Spring JDBC 1.pom.xml <project xmlns=&quo ...

  3. 大数据学习day32-----spark12-----1. sparkstreaming(1.1简介,1.2 sparkstreaming入门程序(统计单词个数,updateStageByKey的用法,1.3 SparkStreaming整合Kafka,1.4 SparkStreaming获取KafkaRDD的偏移量,并将偏移量写入kafka中)

    1. Spark Streaming 1.1 简介(来源:spark官网介绍) Spark Streaming是Spark Core API的扩展,其是支持可伸缩.高吞吐量.容错的实时数据流处理.Sp ...

  4. SparkStreaming+Kafka整合

    SparkStreaming+Kafka整合 1.需求 使用SparkStreaming,并且结合Kafka,获取实时道路交通拥堵情况信息. 2.目的 对监控点平均车速进行监控,可以实时获取交通拥堵情 ...

  5. SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量

    SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...

  6. spark第十篇:Spark与Kafka整合

    spark与kafka整合需要引入spark-streaming-kafka.jar,该jar根据kafka版本有2个分支,分别是spark-streaming-kafka-0-8和spark-str ...

  7. 【转】Spark Streaming和Kafka整合开发指南

    基于Receivers的方法 这个方法使用了Receivers来接收数据.Receivers的实现使用到Kafka高层次的消费者API.对于所有的Receivers,接收到的数据将会保存在Spark ...

  8. Spring Kafka整合Spring Boot创建生产者客户端案例

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 创建一个kafka-producer-master的maven工程.整个项目结构如下: ...

  9. jackson学习之三:常用API操作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. python学习:删除空白

    删除空白   删除尾部空白 确保字符串尾部没有空白,使用rstrip(); 删除字符串开头的空白,使用lstrip(); 同时删除字符串两端的空白,使用strip() 代码: >>> ...

  2. __x__(40)0909第五天__表格 table 的 css 样式 美化

    如果就向下面的代码那样,不写 tbody , 则浏览器自添加 tbody , 并将所有的 tr 移入 tbody 意味着 tr 并非 table 的子元素,而是 tbody 的子元素. 所以 以后编写 ...

  3. vue菜鸟从业记:公司项目里如何进行前后端接口联调

    最近我的朋友王小闰进入一家新的公司,正好公司项目采用的是前后端分离架构,技术栈是王小闰非常熟悉的vue全家桶,后端用的是Java语言. 在前后端开发人员碰面之后,协商确定好了前端需要的数据接口(扯那么 ...

  4. java学习(五)--- 方法

    方法的定义 修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; } 注意:非void方法必须有返回值 方法重载: 可以声明方法相同,但是参数类型不同的方法 ...

  5. SQLSERVER 聚集一个表的字段2008及以后,要求支持XML

    将以下代码中的TABLE_NAME替换成所需表名称即可. 注意 declare 和set 语句后面不要有 :否则可能执行不成功 declare @S_Column varchar(8000)set @ ...

  6. 19.3.19 使用Flask框架搭建一个简易登录服务器

    import Flask import json from Flask import request server1 = flask.Flask(__name__) #实例化一个flask对象 @se ...

  7. JDK8之The type java.util.Map$Entry cannot be resolved

    eclipse+tomcat7+jdk1.6上面报错的方式我的解法方法是吧jre8换成6的就好了选中项目->右键->java build path ->找到jre system li ...

  8. linux用户添加组

    usermod -G groupname username (这种会把用户从其他组中去掉,只属于该组)如:usermod -G git git (git只属于git组) usermod -a -G g ...

  9. python 读取文本文档中的数据

    import os dir = input('Please input the file dir:')#提示输入文件路径 while not os.path.exists(dir):#判断文件是否存在 ...

  10. request之额外路径

    谈到额外路径 ,首先要明白映射路径,映射路径是servlet处理的路径,在web.xml中配置.比如配置一个/emp的映射路径,意味着客户端可以通过http:+项目路径+/emp访问服务器的项目,而所 ...