Kafka Connect S3接收器-如何使用消息本身中的时间戳[时间戳提取器]

时间:2019-03-28 07:55:05

标签: amazon-s3 apache-kafka apache-kafka-connect confluent

我一直在使用kafka connect和S3接收器来解决问题。

首先是结构:

{
   Partition: number
   Offset: number
   Key: string
   Message: json string
   Timestamp: timestamp
}

通常在发布到Kafka时,时间戳应由生产者设置。不幸的是,似乎有些情况没有发生。这意味着时间戳有时可能是null

要提取此时间戳记,请将连接器设置为以下值: "timestamp.extractor":"Record"

现在总是可以确定Message字段本身也总是包含一个时间戳。

Message

{
   timestamp: "2019-04-02T06:27:02.667Z"
   metadata: {
     creationTimestamp: "1554186422667"
   }
}

但是问题是,现在,我想将该字段用于timestamp.extractor

我当时以为这样就足够了,但这似乎行不通:

"timestamp.extractor":"RecordField",
"timestamp.field":"message.timestamp",

这也会导致NullPointer。

关于如何使用kafka消息有效负载本身中的时间戳的任何想法,而不是为kafka v0.10 +设置的默认时间戳字段的任何想法

编辑: 完整配置:

{ "name": "<name>",
  "config": {
    "connector.class":"io.confluent.connect.s3.S3SinkConnector",
    "tasks.max":"4",
    "topics":"<topic>",
    "flush.size":"100",
    "s3.bucket.name":"<bucket name>",
    "s3.region": "<region>",
    "s3.part.size":"<partition size>",
    "rotate.schedule.interval.ms":"86400000",
    "key.converter": "org.apache.kafka.connect.storage.StringConverter",
    "value.converter": "org.apache.kafka.connect.json.JsonConverter",
    "key.converter.schemas.enable": "false",
    "value.converter.schemas.enable": "false",
    "storage.class":"io.confluent.connect.s3.storage.S3Storage",
    "format.class":"io.confluent.connect.s3.format.json.JsonFormat",
    "locale":"ENGLISH",
    "timezone":"UTC",
    "schema.generator.class":"io.confluent.connect.storage.hive.schema.TimeBasedSchemaGenerator",
    "partitioner.class":"io.confluent.connect.storage.partitioner.TimeBasedPartitioner",
    "partition.duration.ms": "3600000",
    "path.format": "'year'=YYYY/'month'=MM/'day'=dd",
    "timestamp.extractor":"RecordField",
    "timestamp.field":"message.timestamp",
    "max.poll.interval.ms": "600000",
    "request.timeout.ms": "610000",
    "heartbeat.interval.ms": "6000",
    "session.timeout.ms": "20000",
    "s3.acl.canned":"bucket-owner-full-control"
  }
}

编辑2: Kafka消息有效负载结构:

{
  "reference": "",
  "clientId": "",
  "gid": "",
  "timestamp": "2019-03-19T15:27:55.526Z",
}

编辑3:

{
"transforms": "convert_op_creationDateTime",
"transforms.convert_op_creationDateTime.type": "org.apache.kafka.connect.transforms.TimestampConverter$Value",
"transforms.convert_op_creationDateTime.target.type": "Timestamp",
"transforms.convert_op_creationDateTime.field": "timestamp",
"transforms.convert_op_creationDateTime.format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
}

所以我尝试对对象进行转换,但是似乎我再次被卡在了这件事上。该模式似乎无效。环顾互联网似乎确实是一个有效的SimpleDatePattern。似乎在抱怨'T'。还更新了消息架构。

2 个答案:

答案 0 :(得分:0)

基于共享的架构,您应该进行设置:

    "timestamp.extractor":"RecordField",
    "timestamp.field":"timestamp",

即时间戳记字段名称前没有message前缀。

答案 1 :(得分:0)

如果数据是字符串,则Connect将尝试解析为毫秒-source code here

无论如何,message.timestamp假设数据看起来像{ "message" : { "timestamp": ... } },所以timestamp才是正确的。而且,嵌套字段过去是不可能的,因此您可能想弄清楚您拥有的Connect版本。

我不确定使用JSON Converter时如何使instanceof Date评估为true,即使您已设置schema.enable = true,也可以在代码中看到仅适用于数字和字符串的架构类型的条件,但仍假定为毫秒。

您可以尝试使用TimestampConverter转换来转换日期字符串。