我是Flink和集群计算的新手。我花了一整天的时间试图在Flink上正确解析来自Kafka的愚蠢流,没有结果:这有点让人沮丧...... 我在kafka中发现了一个用字符串键标识的JSON-LD消息流。我只想在Flink中检索它们,然后用不同的密钥分隔消息。
1) 最初我考虑将消息发送为String而不是JSON-LD。我觉得更容易......
我尝试了所有deserialiser,但都没有。简单的解串器无效但却完全忽略了键。
我相信我必须使用(Flink显然只有两个支持密钥的解串器):
DataStream<Object> stream = env
.addSource(new FlinkKafkaConsumer010<>("topicTest", new TypeInformationKeyValueSerializationSchema(String.class, String.class, env.getConfig()), properties))
.rebalance();
stream.print();
但我得到了:
06/12/2017 02:09:12来源:Custom Source(4/4)切换为FAILED java.io.EOFException的 at org.apache.flink.runtime.util.DataInputDeserializer.readUnsignedByte(DataInputDeserializer.java:306)
如何在不丢失密钥的情况下接收流消息?
2) 我的kafka生成器是用javascript实现的,因为Flink支持JSONDeserialization我虽然直接发送kafka JSON Object。 我不确定JSON-LD能否正常使用,但我已经使用过:
json.parse(jsonld_message)
将json序列化为消息。然后我用普通的字符串键发送了它。
但是在Flink中,这段代码不起作用:
DataStream<ObjectNode> stream = env
.addSource(new FlinkKafkaConsumer010<>("topicTest", new JSONKeyValueDeserializationSchema(false), properties))
.rebalance();
stream.print();
提高
JsonParserException。
我认为第一种方法更简单,我更喜欢它,因为允许及时考虑一个问题(第一种:接收数据,第二种:在JSON-LD中重新转换字符串,我想是外部库)。
答案 0 :(得分:0)
为了使用Flink的TypeInformationKeyValueSerializationSchema
从Kafka读取数据,必须以兼容的方式编写。假设您的密钥和值的类型为String
,那么密钥和值必须以Flink的StringSerializer
理解数据的方式编写。
因此,您必须确保您的Kafka生产者以兼容的方式写入数据。否则Flink'将无法读取数据。
答案 1 :(得分:0)
解决:
最后,我决定实现一个实现KeyedDeserializedSchema接口的自定义反序列化器。
答案 2 :(得分:0)
** 我遇到了类似的问题。理想情况下,带有键和值的字符串类型的 TypeInformationKeyValueSerializationSchema 应该能够读取我的 kafka 记录,该记录将键和值作为字符串。但正如上面的帖子所指出的那样,它无法并且有一个 EOF 异常。所以这个问题很容易重现,需要修复。请让我知道我是否可以在此过程中提供任何帮助。同时使用
实现自定义序列化程序 <块引用>Kafka 解串器架构
。这是代码,因为关于它读取键/值和其他内容的文档很少: **
import org.apache.flink.api.common.typeinfo.TypeHint;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.connectors.kafka.KafkaDeserializationSchema;
import org.apache.kafka.clients.consumer.ConsumerRecord;
public class CustomKafkaSerializer implements KafkaDeserializationSchema<Tuple2<String,String>> {
@Override
public boolean isEndOfStream(Tuple2<String,String> stringStringPair) {
return false;
}
@Override
public Tuple2<String,String> deserialize(ConsumerRecord<byte[], byte[]> consumerRecord) throws Exception {
String key = new String(consumerRecord.key());
String value = new String(consumerRecord.value());
return new Tuple2<>(key,value);
}
@Override
public TypeInformation<Tuple2<String,String>> getProducedType() {
return TypeInformation.of(new TypeHint<Tuple2<String, String>>(){});
}
}