我正在尝试使用flink从kafka读取数据,并执行一些功能,然后将结果返回给不同的Kafka主题,但出现以下错误。 org.apache.flink.api.common.InvalidProgramException:MapFunction的实现不可序列化。该对象可能包含或引用了不可序列化的字段。
` 我从kafka收到消息-对其进行了一些操作,并返回了要发送到其他主题的对象列表。
class Wrapper implements Serializable{
@JsonProperty("viewBuilderRequests")
private ArrayList<ViewBuilderRequest> viewBuilderRequests;
public Wrapper(){}
public Wrapper(ArrayList<ViewBuilderRequest> viewBuilderRequests) {
this.viewBuilderRequests = viewBuilderRequests;
}
public List<ViewBuilderRequest> getViewBuilderRequests() {
return viewBuilderRequests;
}
public void setViewBuilderRequests(ArrayList<ViewBuilderRequest> viewBuilderRequests) {
this.viewBuilderRequests = viewBuilderRequests;
}
}
public class ViewBuilderRequest implements Serializable {
private CdmId cdmId
private ViewBuilderOperation operation
private List<ViewUserSystemIdentifier> viewUserSystemIdentifiers
public ViewBuilderRequest(){
}
public CdmId getCdmId() {
return cdmId;
}
public void setCdmId(CdmId cdmId) {
this.cdmId = cdmId;
}
public ViewBuilderOperation getOperation() {
return operation;
}
public void setOperation(ViewBuilderOperation operation) {
this.operation = operation;
}
public List<ViewUserSystemIdentifier> getViewUserSystemIdentifiers() {
return viewUserSystemIdentifiers;
}
public void setViewUserSystemIdentifiers(List<ViewUserSystemIdentifier> viewUserSystemIdentifiers) {
this.viewUserSystemIdentifiers = viewUserSystemIdentifiers;
}
public enum ViewBuilderOperation implements Serializable{
Create, Update,Delete
}
private MapFunction<String, Wrapper> parseAndSendToGraphProcessing = s ->{
UserMatchingRequest userMatchingRequest = objectMapper.readValue(s, UserMatchingRequest.class);
Wrapper wrapper = new Wrapper(janusGraphDataProcessing.handleMessage(userMatchingRequest));
return wrapper;
};
内部类也实现了Serializable
此代码引发异常:
dataStream.map(parseAndSendToGraphProcessing)
.addSink(new FlinkKafkaProducer<Wrapper>(kafkaConfiguration.getBootstrapServers(),"graphNotifications",new WrapperSchema()));
我还对这两个对象进行了反序列化。
public class WrapperSchema implements DeserializationSchema<Wrapper>, SerializationSchema<Wrapper> {
// private final static ObjectMapper objectMapper = new ObjectMapper().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
static ObjectMapper objectMapper = new ObjectMapper();
@Override
public Wrapper deserialize(byte[] message) throws IOException {
return objectMapper.readValue(message, Wrapper.class);
}
@Override
public boolean isEndOfStream(Wrapper nextElement) {
return false;
}
@Override
public byte[] serialize(Wrapper element) {
// return element.toString().getBytes();
if(objectMapper == null) {
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
objectMapper = new ObjectMapper();
}
try {
String json = objectMapper.writeValueAsString(element);
return json.getBytes();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return new byte[0];
}
@Override
public TypeInformation<Wrapper> getProducedType() {
return TypeInformation.of(Wrapper.class);
}
}
答案 0 :(得分:0)
要使flink正常工作,您的消息和地图函数都必须可序列化。
据我所知,您的邮件似乎可以序列化。
但是您的地图功能不是。有时很难使lambda可序列化。我认为在您的情况下,问题在于parseAndSendToGraphProcessing
使用objectMapper
和janusGraphDataProcessing
,它们必须可序列化。
我的猜测是janusGraphDataProcessing
不可序列化(如果您使用的是jackson 2.1或更高版本,OjbectMapper就是如此)。
如果是这种情况,那么一种解决方法是编写一个自定义RichMapFunction类,该类将janusGraphDataProcessing
存储为瞬时变量,并在其open
函数中对其进行初始化。
private MapFunction<String, Wrapper> parseAndSendToGraphProcessing = s ->{
UserMatchingRequest userMatchingRequest = objectMapper.readValue(s, UserMatchingRequest.class);
Wrapper wrapper = new Wrapper(janusGraphDataProcessing.handleMessage(userMatchingRequest));
return wrapper;
};