抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

SparkStreaming整合Kafka

kafka的两个重要版本

Kafka-0.8

  • consumer在消费消息的时候会记录一个偏移量(offset)

  • offset 偏移量记录上一次消费到哪里了,那么下一次我知道要从哪里继续消费数据

  • 偏移量被保存在 Zookeeper 中

  • 问题:在一个公司里可能有几百号人去消费kafka集群,这个时候zookeeper会面临高并发的读写(zookeeper不擅长高并发读写,zookeeper是有问题的)这个设计明显是有问题的

Kafka-0.10

  • 不再在zookeeper中存储offset了

  • 在kafka中设计了一个特殊topic(__consumer_offset),将所有的consumer中的所有offset存在了这个topic中

  • 这个用来存储offset的topic默认50个分区,如果集群足够大的话那么这些分区也会均匀的分布在整个集群中支持高并发的读写,这样高并发的读写就不会成为瓶颈了

0.8-kafka(zookeeper) 和 0.10-kafka(kafka)的offset是怎么提交的?

自动提交offset,这样整个系统就可能面临丢失数据的风险

SparkStreaming 防数据丢失设计

Kafka每隔5秒提交一次offset,如果这样我们的程序就有可能丢数据,为什么?

SparkStreaming读取到了kafka的数据(offset=100),还没有处理正好遇到了5s的时间间隔提交了offset

这个时候offset已经提交了,但是等到处理的时候,发现处理失败了

这样重启的时候数据就发生了丢失,我们企业中当然是不允许数据丢失的

怎么解决丢数据的问题呢?

kafka-0.8:把自动提交offset关掉,改成手动提交offset,但是这个时候有可能出现数据重复;因为你在提交offset的时候有可能失败,所以就会重复的消费数据进行处理,但是这个总好过丢数据,并且可以根据幂等性等一些方案对重复数据进行过滤,来保证数据不丢失的前提下保证唯一性

kafka-0.10:和kafka-0.8一样关闭自动提交offset,改成手动提交,只是offset存储的地方不一样

实时处理系统中对数据处理的策略

  • At most once 一条记录要么被处理一次,要么没有被处理(丢数据)

  • At least once 一条记录可能被处理一次或者多次,可能会重复处理(重复消费)

  • Exactly once 一条记录只被处理一次(仅一次)

要想实现仅一次语义

  • 数据的输入:从上一次offset读取数据 offset

  • 数据的处理:Spark 本身就有容错,所以天然的就保证了Exactly-Once

  • 数据的输出:利用事务去实现

留言区