现象

一批 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 数据。

问题解决

我们可以通过下面两种方式进行解决

  1. 设置不同的 batchDuration
  2. 改写 RecurringTimer#getStartTime 的逻辑,在上述对齐的时间基础上加上一个 [0, period) 范围内的随机数

我们知道在上述两种解决方案中,第一种,不同作业还是会在某一时刻重合,而且这个重合的时间点不可控,可能是作业运行一小时后,可能是运行一天后,也可能是运行一周后。而第二种作业则是可控的,在作业启动时就决定了。因此这里我们采用第二种方案。

本文采用了一种新的排版方式,在进行实验,如果效果好的好,后续大部分内容都会以这种形式进行发布

Comments