Streaming & Kafka
SparkStreaming 整合 Kafka
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),还没有处理正好遇到了 5
s 的时间间隔提交了 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
数据的输出:利用事务去实现