问题::当recordProcessor的子线程数很高时,在recordProcessor上多次调用initialize(...)
方法。
环境:
AWS开发工具包:1.11.498
KCL:1.9.3
斯卡拉:2.12.8
JDK:OpenJDK 1.8
主机:ECS上的Amazon Linux 2 [ami-007571470797b8ffa]
分片数量:8
实施:
我已经在Scala中实现了RecordProcessor(扩展了IRecordProcessor)。
-该记录处理器在initialize(...)
上启动统计信息报告线程,以将统计信息报告给我们的收集者。
-而且,当调用processRecords(...)
时,此记录处理器通过工作队列在内部在多个工作线程之间分配要处理的记录。这些工作线程也在initialize(...)
上启动。
问题:
当分片计数为8并且工作线程计数为16时,KCL在同一recordProcessor上多次调用initialize(...)
方法。当先前的IllegalThreadStateException
调用已尝试启动statsReporterThread
时,将引发initialize(...)
。
捕获:
当分片计数仍为8,但工作线程计数为1时,不会进行多个initialize(...)
调用,并且一切正常。
由于工作线程没有暴露于KCL,这令人困惑,它们是记录处理器的内部实现。
我怀疑下限值较低,所以我增加了下限值,但无济于事。
此外,当我的笔记本电脑上运行相同的应用程序时,它也可以工作!但是在AWS ECS上失败。
代码:
class RecordProcessor() extends IRecordProcessor {
val statsReporter = new StatsReporter()
val statsReporterThread = new Thread(statsReporter)
val workQueue: LinkedBlockingDeque[Record] = ...
val workerThreads: ListBuffer[Thread] = ...
def initialize(shardId) = {
statsReporterThread.start()
(0 until 16).foreach(_ => {
val wThread = new Thread(new Worker(workQueue))
workerThreads += wThread
wThread.start()
})
}
def processRecords(records, checkpointer) = {
records.foreach(record => {
wq.put(record)
})
if (currentTimeMs > nextTimeInMs) {
checkpoint(checkpointer)
nextTimeInMs = currentTimeMs + 15000
}
}
def shutdown(checkpointer, reason) = {
workerThreads.foreach(w => {
w.interrupt()
w.join()
})
statsReporterThread.interrupt()
statsReporterThread.join()
}
}
class Worker(workQueue) extends Runnable {
override def run(): Unit = {
while (!Thread.currentThread().isInterrupted) {
val record = q.take()
process(record)
}
}
}
任何帮助/指针将不胜感激!
谢谢!