将kafka-connect-transform-archive与HdfsSinkConnector一起使用时的刷新大小

时间:2019-04-26 10:10:06

标签: apache-kafka hdfs apache-kafka-connect confluent

我的Kafka主题中有数据,我想保留在数据湖中。

在担心按键之前,我能够使用HdfsSinkConnector将Avro值保存在数据湖上的文件中。每个文件中消息值的数量由HdfsSinkConnector的“ flush.size”属性确定。

一切都很好。接下来,我也想保留密钥。为此,我使用了kafka-connect-transform-archive,它将String键和Avro值包装到新的Avro模式中。

这很好用...除了现在忽略HdfsSinkConnector的flush.size。保存在数据湖中的每个文件仅具有1条消息。

因此,两种情况是1)仅保存值,每个文件中的值数由flush.size确定; 2)保存键和值,每个文件中仅包含一条消息和flush.size被忽略。

这两种情况之间的唯一区别是HdfsSinkConnector的配置,该配置指定了存档转换。

"transforms": "tran",
"transforms.tran.type": "com.github.jcustenborder.kafka.connect.archive.Archive"

kafka-connect-transform-archive是否根据设计忽略了刷新大小,还是我需要一些其他配置才能将每个文件中的多个键值消息保存在数据湖上?

1 个答案:

答案 0 :(得分:0)

使用kafka gcs接收器连接器时,我遇到了同样的问题。

在com.github.jcustenborder.kafka.connect.archive.Archive代码中,每条消息都会创建一个新的Schema。

private R applyWithSchema(R r) {
final Schema schema = SchemaBuilder.struct()
    .name("com.github.jcustenborder.kafka.connect.archive.Storage")
    .field("key", r.keySchema())
    .field("value", r.valueSchema())
    .field("topic", Schema.STRING_SCHEMA)
    .field("timestamp", Schema.INT64_SCHEMA);
Struct value = new Struct(schema)
    .put("key", r.key())
    .put("value", r.value())
    .put("topic", r.topic())
    .put("timestamp", r.timestamp());
return r.newRecord(r.topic(), r.kafkaPartition(), null, null, schema, value, r.timestamp());

}

如果您看一下kafka转换InsertField $ Value方法,您会发现它使用SynchronizedCache以便每次都检索相同的模式。

https://github.com/axbaretto/kafka/blob/ba633e40ea77f28d8f385c7a92ec9601e218fb5b/connect/transforms/src/main/java/org/apache/kafka/connect/transforms/InsertField.java#L170

因此,您只需要创建一个架构(在apply函数之外)或使用相同的SynchronizedCache代码。