我尝试为自定义类实现一个方法,使用Flink Kafka连接器在Kafka上生成数据。类原型如下:
public class StreamData implements Serializable {
private transient StreamExecutionEnvironment env;
private DataStream<byte[]> data ;
...
将数据写入特定Kafka主题的方法如下:
public void writeDataIntoESB(String id) throws Exception {
FlinkKafkaProducer011<byte[]> producer = new FlinkKafkaProducer011<byte[]>(
"localhost:9092",
id,
new KeyedSerializationSchema<byte[]>() {
@Override
public byte[] serializeKey(byte[] bytes) {
return bytes;
}
@Override
public byte[] serializeValue(byte[] bytes) {
return bytes;
}
@Override
public String getTargetTopic(byte[] bytes) {
return null;
}
});
data.addSink(producer);
}
我有另一种方法可以将数据从Kafka主题获取到对象的data
字段,这样可以正常工作。现在尝试从Kafka主题获取数据并将其写入另一个Kafka主题我得到了错误:
org.apache.flink.api.common.InvalidProgramException: Object StreamData$2@1593948d is not serializable
主要代码:
StreamData temp = new StreamData();
temp = temp.getDataFromESB("data", 0);
temp.writeDataIntoESB("flink_test");
似乎Java试图序列化对象而不仅仅是字段data
!使用Flink Kafka连接器向Kafka生成数据的代码经过测试,可以正常使用(我的意思是不使用类并在main中编写所有代码)
我怎样才能消除错误?
答案 0 :(得分:2)
我认为问题的原因是您的代码正在执行此操作:
new KeyedSerializationSchema<byte[]>() {...}
这段代码的作用是创建一个KeyedSerializationSchema的匿名子类作为定义类(StreamData)的内部类。每个内部类都包含对外部类实例的隐式引用,因此使用默认Java序列化规则对其进行序列化也将传递尝试序列化外部对象(StreamData)。解决此问题的最好方法是将KeyedSerializationSchema的子类声明为:
我认为最后一种方法看起来像这样:
public class StreamData {
static KeyedSerializationSchema<byte[]> schema = new KeyedSerializationSchema<byte[]>() {
...
};
...
public void writeDataIntoESB(String id) throws Exception {
FlinkKafkaProducer011<byte[]> producer = new FlinkKafkaProducer011<byte[]>("localhost:9092", id, schema);
data.addSink(producer);
}
}
答案 1 :(得分:0)
将data
属性设为静态,解决了问题。任何人都可以详细说明这个并且它是一个很好的解决方案吗?
private static DataStream<byte[]> data ;
答案 2 :(得分:0)
您也可以像这样在Flink中进行序列化
dataStream.addSink(new FlinkKafkaProducer<KafkaObject>(ProducerTopic, new
CustomSerializerSchema(),properties));
public class CustomSerializerSchema implements SerializationSchema<MyUser> {
private static final long serialVersionUID = 1L;
@Override
public byte[] serialize(MyUser element) {
byte[] b = null;
try {
b= new ObjectMapper().writeValueAsBytes(element);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return b;
}
}