Spark Streaming 统一在每分钟的 00 秒消费 Kafka 数据的问题解决
现象
一批 Spark Streaming 会统一在每分钟的 00 秒开始消费 kafka 数据
问题排查
这一批作业的功能就是从 kafka 消费数据,进行转化后存储到外部可靠介质中。所有作业的 batchDuration
都设置为 60s。
我们追踪代码可以得到在 JobGenerator
中有一个变量 timer : RecurringTimer
,改变量用于定时的启动 task 去消费数据。
从 RecurringTimer#getStartTime
我们可以得到作业第一个 batch 的启动时间,后续的 batch 启动时间则是在第一个 batch 的启动时间上加上 batchDuration
的整数倍。
第一个 batch 的起动时间实现如下:(math.floor(clock.getTimeMillis().toDouble / period) + 1).toLong * period
其中 clock.getTimeMillis()
是当前时间,period 是batchDuration
的毫秒表示法。通过上述公式,我们可以知道作业的启动时间会对齐到 batchDuration
,而我们把这一批作业的 batchDuration
都设置为 60s,因此都会在每分钟的 00 秒开始消费 kafka 数据。
问题解决
我们可以通过下面两种方式进行解决
- 设置不同的
batchDuration
- 改写
RecurringTimer#getStartTime
的逻辑,在上述对齐的时间基础上加上一个 [0, period) 范围内的随机数
我们知道在上述两种解决方案中,第一种,不同作业还是会在某一时刻重合,而且这个重合的时间点不可控,可能是作业运行一小时后,可能是运行一天后,也可能是运行一周后。而第二种作业则是可控的,在作业启动时就决定了。因此这里我们采用第二种方案。
本文采用了一种新的排版方式,在进行实验,如果效果好的好,后续大部分内容都会以这种形式进行发布