如果是使用spark-streaming-kafka-0-10,那么我们建议将enable.auto.commit
设为false。这个配置只是在这个版本生效,enable.auto.commit
如果设为true的话,那么意味着offsets会按照auto.commit.interval.ms
中所配置的间隔来周期性自动提交到Kafka中。在Spark Streaming中,将这个选项设置为true的话会使得Spark应用从kafka中读取数据之后就自动提交,而不是数据处理之后提交,这不是我们想要的。所以为了更好地控制offsets的提交,我们建议将enable.auto.commit
设为false。
一、将Offsests存储在外部系统
1、kafka本身
2、外部存系统
zookeeper、hbase、mysql、redis等
3、sparkstreaming的checkpoint
4、其他方式
你也可以将offsets存储到HDFS中。但是将offsets存储到HDFS中并不是一个受欢迎的方式,因为HDFS对已ZooKeeper和Hbase来说它的延迟有点高。此外,将每批次数据的offset存储到HDFS中还会带来小文件的问题
二、不管理offsets
管理offsets对于Spark Streaming应该用来说并不是必须的。举个例子,像应用存活监控它只需要当前的数据,并不需要通过管理offsets来保证数据的不丢失。这种情形下你完全不需要管理offsets,老的kafka消费者可以将auto.offset.reset
设为largest或者smallest,而新的消费者则设置为earliest or latest。
如果你将auto.offset.reset
设为smallest (earliest),那么任务会从最开始的offset读取数据,相当于重播所有数据。这样的设置会使得你的任务重启时将该topic中仍然存在的数据再读取一遍。这将由你的消息保存周期来决定你是否会重复消费。
相反地,如果你将auto.offset.reset
设置为largest (latest),那么你的应用启动时会从最新的offset开始读取,这将导致你丢失数据。这将依赖于你的应用对数据的严格性和语义需求,这或许是个可行的方案。