我在kafka 2.0.0中使用融合的hdfs接收器连接器5.0.0,我需要使用ExtractTopic转换(https://docs.confluent.io/current/connect/transforms/extracttopic.html)。我的连接器工作正常,但是当我添加此转换时,即使在只有2个属性的简单数据样本上,也会出现NullPointerException。
ERROR Task hive-table-test-0 threw an uncaught and unrecoverable exception (org.apache.kafka.connect.runtime.WorkerSinkTask:482)
java.lang.NullPointerException
at io.confluent.connect.hdfs.DataWriter.write(DataWriter.java:352)
at io.confluent.connect.hdfs.HdfsSinkTask.put(HdfsSinkTask.java:109)
at org.apache.kafka.connect.runtime.WorkerSinkTask.deliverMessages(WorkerSinkTask.java:464)
at org.apache.kafka.connect.runtime.WorkerSinkTask.poll(WorkerSinkTask.java:265)
at org.apache.kafka.connect.runtime.WorkerSinkTask.iteration(WorkerSinkTask.java:182)
at org.apache.kafka.connect.runtime.WorkerSinkTask.execute(WorkerSinkTask.java:150)
at org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:146)
at org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:190)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这是连接器的配置:
name=hive-table-test
connector.class=io.confluent.connect.hdfs.HdfsSinkConnector
tasks.max=1
topics=hive_table_test
key.converter=io.confluent.connect.avro.AvroConverter
value.converter=io.confluent.connect.avro.AvroConverter
key.converter.schema.registry.url=${env.SCHEMA_REGISTRY_URL}
value.converter.schema.registry.url=${env.SCHEMA_REGISTRY_URL}
schema.compatibility=BACKWARD
# HDFS configuration
# Use store.url instead of hdfs.url (deprecated) in later versions. Property store.url does not work, yet
hdfs.url=${env.HDFS_URL}
hadoop.conf.dir=/etc/hadoop/conf
hadoop.home=/opt/cloudera/parcels/CDH/lib/hadoop
topics.dir=${env.HDFS_TOPICS_DIR}
# Connector configuration
format.class=io.confluent.connect.hdfs.avro.AvroFormat
flush.size=100
rotate.interval.ms=60000
# Hive integration
hive.integration=true
hive.metastore.uris=${env.HIVE_METASTORE_URIS}
hive.conf.dir=/etc/hive/conf
hive.home=/opt/cloudera/parcels/CDH/lib/hive
hive.database=kafka_connect
# Transformations
transforms=InsertMetadata, ExtractTopic
transforms.InsertMetadata.type=org.apache.kafka.connect.transforms.InsertField$Value
transforms.InsertMetadata.partition.field=partition
transforms.InsertMetadata.offset.field=offset
transforms.ExtractTopic.type=io.confluent.connect.transforms.ExtractTopic$Value
transforms.ExtractTopic.field=name
transforms.ExtractTopic.skip.missing.or.null=true
我正在使用架构注册表,数据为avro格式,并且我确定给定属性name
不为null。有什么建议么?我基本上需要提取给定字段的内容并将其用作主题名称。
编辑:
即使在像avro格式这样的简单json上,它也会发生:
{
"attr": "tmp",
"name": "topic1"
}
答案 0 :(得分:1)
答案很简单,是因为您在“转换”中更改了主题名称。
每个主题分区的 Hdfs连接器具有单独的TopicPartitionWriter
。当创建SinkTask时,将为每个分区open(...)
的{{1}}方法创建负责处理消息的消息。
当处理SinkRecords时,它根据 topic 名称和 partition 编号查找TopicPartitionWriter
,并尝试将记录追加到其缓冲区中。在您的情况下,找不到任何写消息。主题名称已通过“转换”更改,对于该对(主题,分区),未创建任何TopicPartitionWriter
。
传递到TopicPartitionWriter
的SinkRecords已设置了分区和主题,因此您不必应用任何转换。
我认为HdfsSinkTask::put(Collection<SinkRecord> records)
应该用于io.confluent.connect.transforms.ExtractTopic
。