我正在Kafka Connect中编写一个SinkConnector并遇到问题。该连接器具有这样的配置:
{
"connector.class" : "a.b.ExampleFileSinkConnector",
"tasks.max" : '1',
"topics" : "mytopic",
"maxFileSize" : "50"
}
我这样定义连接器的配置:
@Override public ConfigDef config()
{
ConfigDef result = new ConfigDef();
result.define("maxFileSize", Type.STRING, "10", Importance.HIGH, "size of file");
return result;
}
在连接器中,我这样启动任务:
@Override public List<Map<String, String>> taskConfigs(int maxTasks) {
List<Map<String, String>> result = new ArrayList<Map<String,String>>();
for (int i = 0; i < maxTasks; i++) {
Map<String, String> taskConfig = new HashMap<>();
taskConfig.put("connectorName", connectorName);
taskConfig.put("taskNumber", Integer.toString(i));
taskConfig.put("maxFileSize", maxFileSize);
result.add(taskConfig);
}
return result;
}
一切顺利。
但是,在启动Task时(在taskConfigs()中),如果我添加了它:
taskConfig.put("epoch", "123");
这破坏了整个基础架构:所有连接器都以无休止的循环停止和重新启动。
连接日志文件中没有任何异常或错误可以帮助您。
使其生效的唯一方法是在连接器配置中添加“ epoch”,我不想这样做,因为它是连接器必须发送给任务的内部参数。不应将其暴露给连接器的用户。
我注意到的另一点是,除了将其设置为默认值之外,无法更新任何连接器配置参数的值。更改参数并将其发送到任务会产生相同的行为。
在此问题上的任何帮助,我将非常感谢。
编辑:这是SinkTask :: start()
的代码@Override public void start(Map<String, String> taskConfig) {
try {
connectorName = taskConfig.get("connectorName");
log.info("{} -- Task.start()", connectorName);
fileNamePattern = taskConfig.get("fileNamePattern");
rootDir = taskConfig.get("rootDir");
fileExtension = taskConfig.get("fileExtension");
maxFileSize = SimpleFileSinkConnector.parseIntegerConfig(taskConfig.get("maxFileSize"));
maxTimeMinutes = SimpleFileSinkConnector.parseIntegerConfig(taskConfig.get("maxTimeMinutes"));
maxNumRecords = SimpleFileSinkConnector.parseIntegerConfig(taskConfig.get("maxNumRecords"));
taskNumber = SimpleFileSinkConnector.parseIntegerConfig(taskConfig.get("taskNumber"));
epochStart = SimpleFileSinkConnector.parseLongConfig(taskConfig.get("epochStart"));
log.info("{} -- fileNamePattern: {}, rootDir: {}, fileExtension: {}, maxFileSize: {}, maxTimeMinutes: {}, maxNumRecords: {}, taskNumber: {}, epochStart : {}",
connectorName, fileNamePattern, rootDir, fileExtension, maxFileSize, maxTimeMinutes, maxNumRecords, taskNumber, epochStart);
if (taskNumber == 0) {
checkTempFilesForPromotion();
}
computeInitialFilename();
log.info("{} -- Task.start() END", connectorName);
} catch (Exception e) {
log.info("{} -- Task.start() EXCEPTION : {}", connectorName, e.getLocalizedMessage());
}
}
答案 0 :(得分:0)
我们找到了问题的根本原因。 Kafka Connect Framework实际上是按设计方式运行的-问题与我们尝试使用taskConfigs配置框架的方式有关。
问题
在我们的设计中,FileSinkConnector在其start()生命周期方法中设置了一个纪元,并且通过taskConfigs()生命周期方法将该纪元传递给其任务。因此,每次连接器的start()生命周期方法运行时,都会为任务生成不同的配置-这就是问题所在。
每次都必须生成不同的配置。事实证明,Connect Framework将检测配置差异,并在检测到时重新启动/重新平衡-停止并重新启动连接器/任务。重新启动将调用连接器的stop()和start()方法……这(当然)将产生另一个配置更改(由于新时期),并且恶性循环已经开始!
这是一个有趣且出乎意料的问题……由于Connect中的行为,我们对此并不感激。这是我们第一次尝试生成任务配置,这不是连接器配置的简单功能。
请注意,Connect中的这种行为是有意的,它解决了动态更改配置的实际问题-例如JDBC Sink Connector,当它检测到要接收的新数据库表时自发更新其配置。
感谢那些帮助了我们的人!