spark进阶4

Spark Streaming

spark stream是流式计算框架,支持可扩展,高吞吐量,容错的准实时的数据流处理.

1.SparkStreaming与storm的区别

  • Storm是实时的流式处理框架,SparkStreaming是准实时的处理框架(微批处理),因为是微批处理,所以SparkStreaming的吞吐量比Storm高
  • Storm的事务机制要相对完善
  • Storm支持动态资源调度(spark1.2之后也支持)
  • Sparkstreaming擅长处理复杂的业务处理,storm相比较不擅长,更擅长简单的汇总型计算

2.sparkStreaming的内部执行

在这里插入图片描述

  • 要点注意
    • receive task是7*24小时在执行,一直接受数据.讲一段时间内接收到的数据保存到一个batch中,可以设置batchInterval的时间,那么会将接收过来的数据按照设置的时间封装到一个batch中,batch是没有分布式计算的,这一个batch又被封装到一个RDD中,然后在封装到一个Dstream中.
    • 计算job的时间大于batchInterval的时间会以下问题
      • 如果接收过来的数据设置的级别仅是内存,那么就会形成数据堆积,最后导致OOM,
      • 如果数据设置的级别包含disk,则内存存放不下的数据会溢写到diak中,加大延迟

3.SparkStreaming 算子

  • output operation算子
    • foreachRDD
      • 对抽取出来的RDD执行action类算子
  • transformation类算子
    • transform
      • 对Dstream做RDD到RDD的任意操作
    • updateStateByKey
      • 为sparkstreaming中的每一个Key维护一个state状态,state类型可以是任何类型的,也可以是一个自定义对象,更新函数也可以是自定义的
      • 通过更新函数来对key进行不断的更新,对于每个新的batch而言,sparkStreaming会使用updateStateBykey为已经存在的key进行state的状态进行更新
      • 使用updateStateByKey要开启checkpoint机制和功能
      • 多长时间会将内存中的数据写入的磁盘中
        • 如果batchInterval设置的时间小于10秒,那么10秒写入一次
        • 如果设置的大于10秒,那么就会以设置的时间间隔写入磁盘一份
  • 窗口操作
    • 示意图

在这里插入图片描述

  • 窗口长度和滑动间隔必须要是batchInterval的整数倍,如果不是整数倍会检测报错.
  • 优化后的窗口操作示意图

在这里插入图片描述

  • 优化后的window操作要保存状态,所以要设置checkpoint路径,没有优化的window操作可以不设置checkpoint路径

3.driver的HA(standalone或者是Mesos)

  • sparkStreaming是一直不间断的运行中,driver是一个简单的进程,随时会挂掉.所以要设置driver的HA.client模式无法实现HA,只有集群模式可以.yarn模式下的AM相当于driver.挂掉之后master会查询启动,
    • 提交代码是假–supervise,当driver挂掉的时候会重新启动
    • 使用javastreamingcontext.getorcreat(checkpoint的路径,JavaStreamingContextFactor)

4.SparkStreaming2.2(包含以前)+Kafka0.8之间的整合

  • receive模式
    • sparkstreaming程序运行后,executor里会有一个receive tasks接收kafka推送过来的数据.
    • 根据设置的持久化类型对数据进行备份memory_and_disk_ser_2(2个备份,可以修改),
    • 备份ok后,去zookeeper中更新偏移量,然后向driver中的receive tasks发送数据的位置
    • 最后driver根据数据本地化将task发送到不同的节点

在这里插入图片描述

  • receive存在的问题
    • 当drvier进程挂掉之后,同样的driver下的executor也会挂掉,当更新zookeeper消费偏移量时,就会存在找不到数据,向当于数据丢失
    • 解决办法:
      • 开启WAL机制,当数据备份的时候同时提交一份到HDFS上,当driver挂掉重启之后,会自动计算hdfs上遗留下来的数据,虽然它可以解决数据丢失的问题,但是因为是同时将数据放到HDFS上,会造成流计算性能下降,可以改变默认的备份级别来提高一点性能
    • 开启WAL机制会照成的问题:
      • 数据保存到HDFS上后,要提交偏移量到zookeeper上,但是driver挂了,会导致偏移量提交失败,重启driver之后,会先计算hdfs上面的数据,在读取zookeeper上的偏移量,在读取kafka上面的数据,这时就会造成数据的重复消费.
    • receive的并行设置
      • 并行度由spark.streaming.blockInterva来决定的,默认为200ms,向提高并行度可以减少它的参数,但是不要低于50ms

在这里插入图片描述

  • direct模式
    • direct模式是将kafka看成存数据的一方,不是被动接受数据,而是主动去拉取数据,消费者偏移量由sparkstreaming内部自己管理,如果设置了checkpoint,那么偏移量也会保存在checkpoint中
    • direct模式并行度由读取的kafka中topic的partition决定的

在这里插入图片描述

  • receive模式&direct模式总结
    • receive模式
      • 采用了receive接收器模式,需要一个线程一直接收数据,将数据接收到executor中,默认存储级别MEMORY_AND_DISK_SER_2
      • 自动使用zookeeper管理消费者offest
      • receiver模式底层读取Kafka 采用High Level Consumer API 实现,这种模式不关心offset,只要数据
      • receiver模式当Driver挂掉时,有丢失数据问题,可以开启WAL机制 避免丢失数据,但是开启之后加大了数据处理延迟 ,并且存在数据重复消费风险
      • receiver模式并行度由spark.streaming.blockInterval = 200ms ,可以减少这个参数增大并行度,最小不能低于50ms
      • Receiver模式不被使用
        • 被动将数据接收到Executor,当有任务堆积时,数据存储问题
        • 这种模式不能手动维护消费者offset
    • direct模式
      • 有使用receiver接收器模式,每批次处理数据直接获取当前批次数据处理
      • 没有使用zookeeper管理消费者offset,使用的是Spark自己管理,默认存在内存中,可以设置checkpoint,也会保存到checkpoint中一份
      • 底层读取Kafka使用 Simple Consumer API ,可以手动维护消费者offset
      • direct模式并行度 与读取的topic的partition 一一对应
      • 可以使用设置checkpoint的方式管理消费者offset, 使用StreamingContext.getOrCreate(ckDir,CreateStreamingContext) 恢复
        • 这种方式有两种缺点
          • 第一:当代码逻辑改变时,无法从checkpoint中来恢复offse
          • 第二:当从checkpoint中恢复数据时,有可能造成重复的消费,需要我们写代码来保证数据的输出幂等
      • 如果代码逻辑改变,就不能使用checkpoint模式管理offset,可以手动维护消费者offset,可以将offset存储到外部系统

5.kafka0.11与kafka0.8的差异

  • kafka0.8

    • 消费者offset由zookeeper管理,对于zookeeper来说每次写操作代价很昂贵,而zookeeper集群是不能扩展写能力
  • kafka0.11

    • 消费者offset默认使用新的消费者api,offset会更新到kafka的自带的topic中[_consumer_offset],以消费者组groupid为单位,可以查询每一个组的消费情况

    • #查看所有消费者组
      ./kafka-consumer-groups.sh --bootstrap-server node1:9092, node2:9092, node3:9092 --list
      
      #查看消费者消费的offset位置信息
      ./kafka-consumer-groups.sh --bootstrap-server node1:9092, node2:9092, node3:9092  --describe --group MyGroupId
      
      #重置消费者组的消费offset信息 ,--reset-offsets –all-topics 所有offset。--to-earliest 最小位置。
      # --execute 执行
      ./kafka-consumer-groups.sh --bootstrap-server c7node1:9092,c7node2:9092,c7node3:9092 --group MyGroupId --reset-offsets --all-topics --to-earliest --execute
      

6.sparkstreaming2.3+kafka0.11之间的整合

  • 丢弃了之前的receiver模式
  • 采用了新的消费者api实现,类似于之前Sparkstreaming读取kafka卡的direct模式,并行度一样
  • 一般情况下,sparkstreaming读取数据使用locationStrategies.Prefersistent,这种策略会将分区均匀的分布在集群的Executor之间
    • 如果executor在kafka的某些节点上,可以使用locationStrategies.PreferBrokers,那么当前这个executor中的数据会来自这个broker节点
    • 如果加点明显分布不均,可以使用locationStrategies.preferFixed,可以通过一个map指定topic分区分布在哪些节点上
  • 新的消费者api可以将kafka中的数据预读取到缓存区中,默认为64k,默认的缓存区在Executor.可以通过设置参数spark.streaming.kafka.consumer.cache.maxCapacity 来增大,也可以通过spark.streaming.kafka.consumer.cache.enabled 设置成false 关闭缓存机制
  • 新的消费者offset
    • 设置checkpoint,那么偏移量存储在checkpoint中,
      • 当代码逻辑改变时,无法从checkpoint中恢复偏移量
      • 当从checkpoint中获取偏移量时,可能会出现重复消费,需要写代码来保证数据的输出幂等.
    • 依靠kafka来存储偏移量,kafka中有一个topic来存储消费者offset,在新的消费者api中,偏移量会定期自动提交,自动提交offset的频率由参数auto.commit.interval.ms来决定,默认为5s,为了数据的精确性,可以改为异步手动提交
      • offset存储在kafka中由参数offsets.retention.minutes=1440控制是否过期删除,默认是保存一天,如果停机没有消费达到时长,存储在kafka中的消费者组会被清空,offset也就被清除了
      • 无法保证有且只有一次语义,因为偏移量的提交是异步的,所有若结果的输出依然要自己实现幂等性。
        s.retention.minutes=1440控制是否过期删除,默认是保存一天,如果停机没有消费达到时长,存储在kafka中的消费者组会被清空,offset也就被清除了
      • 无法保证有且只有一次语义,因为偏移量的提交是异步的,所有若结果的输出依然要自己实现幂等性。
      • 自己存储offset,这样在处理逻辑时,保证数据处理的事务,如果处理数据失败,就不保存offset,处理数据成功则保存offset.这样可以做到精准的处理一次处理数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值