Spark Streaming offset的管理那些事!

Spark Streaming offset的管理那些事!

1.Kafka 消息的管理办法
(1) topic
topic中包含多个分区,建议分区是Kafka broker的整数倍,或者是磁盘的整数倍

分区数是Kafka存储的主要概念,key的Hash&numPartition,在分区里存储的时候,offset-msg

消费者 消费消息 首先会自己确定offset的范围,然后使用该范围去kafka
指定topic的指定分区去取消息

消费者消费消息的两个条件:
(1)自己清楚自己消费消息的offset范围,一消费者要自己维护offset在内存,然后定期提交到
第三方存储比如:zk(第三方),kafka。
主动去kafka拉去消息

(内存中有个offset《记录范围》告诉 这次消费到哪里,下次要取消息的时候从哪里开始消费)
高阶Api:
AutoCommit offset
有个线程定期去提交offset(高级 自动维护管理offset)

低阶Api:
它也管理和维护着offset,但是他没有自动去提交offset到 zk或者kafka

2.spark streaming 与kafka结合offset的管理(由于SparkStreaing是分布式的,也即最终输出的时候会有多个任务在多个地方输出到结果库
这样可以实现在单个任务或者分区内部一个事务同时提交offset和结果,但是多个任务或者分区
无法实现在同一个事务内将结果和offset提交到支持事务的结果库)
flink支持分布式事务,Sparkstreaming不支持,那么只能在最后输出的时候进行rpartition成1个分区(超大型数据库不靠谱)

(1) 消费语义的问题:

前提:应用回复故障的时候会从offset存储的地方获取最后提交的offset

仅一次消费(实现起来比较困难)
offset和结果同时一个事务内提交

最多一次消费《丢失数据的,并不是我们所希望的》
先提交offset,再提交结果,这实现最多一次

最少一次消费《很容易实现的》

为什么最少一次消费容易实现:—>

先提交结果,再提交offset,这个时候就是最少消费一次消费语义
《数据重复消费》
(在结果输出之后并且offset输出之前应用程序挂掉,故障恢复后从最后一次提交成功的offset处恢复,会导致数据重复处理。)

那么为了避免有些业务不能重复输出结果,要求我们
1.结果输出要支持幂等性,
2.也可以进行去重
3.要么就是存在更新不存在删除

Receive的形式=>
消费者会定期提交offset到zk中去

版本0.8X 0.1X 用的比较多,其他版本都不敢用 怕不稳定
kafka 010
kafka 082 Receiver

kafka 082 Direct 不给它offset的话, 或者会采用auto.offset.reset

如果,消费者首次启动,内存中没有offset
设置(auto.offset.reset)-自动重置offset

010
largest(旧) 最大或者是最新的offset latest (新)
smallest(旧) 最小或者是最老的offset earliest (新)

010
largest 最大或者是最新的offset
earliest 最小或者是最老的offset

如下为Kafka的一个工具类:

在这里插入代码片object MyKafkaUtil {
    private val properties: Properties = PropertiesUtil.load("config.properties")
    val broker_list = properties.getProperty("kafka.broker.list")

    // kafka消费者配置
    val kafkaParam = Map(
        "bootstrap.servers" -> broker_list,//用于初始化链接到集群的地址
        "key.deserializer" -> classOf[StringDeserializer],
        "value.deserializer" -> classOf[StringDeserializer],
        //用于标识这个消费者属于哪个消费团体
        "group.id" -> "gmall_consumer_group",
        //如果没有初始化偏移量或者当前的偏移量不存在任何服务器上,可以使用这个配置属性
        //可以使用这个配置,latest自动重置偏移量为最新的偏移量
        "auto.offset.reset" -> "latest",
        //如果是true,则这个消费者的偏移量会在后台自动提交,但是kafka宕机容易丢失数据
        //如果是false,会需要手动维护kafka偏移量
        "enable.auto.commit" -> (true: java.lang.Boolean)
    )

    // 创建DStream,返回接收到的输入数据
    // LocationStrategies:根据给定的主题和集群地址创建consumer
    // LocationStrategies.PreferConsistent:持续的在所有Executor之间分配分区
    // ConsumerStrategies:选择如何在Driver和Executor上创建和配置Kafka Consumer
    // ConsumerStrategies.Subscribe:订阅一系列主题

    def getKafkaStream(topic: String,ssc:StreamingContext): InputDStream[ConsumerRecord[String,String]]={
        val dStream = KafkaUtils.createDirectStream[String,String](ssc, LocationStrategies.PreferConsistent,ConsumerStrategies.Subscribe[String,String](Array(topic),kafkaParam))
        dStream
    }***********************************
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值