[英]Flink schema evolution not working for broadcast state
我在 flink 中使用廣播 state 模式,我試圖連接兩個流,一個 stream 是規則的控件 stream,另一個 stream 是整數的 stream(用於虛擬播放目的)。
我有以下Rule
class
public class Rule {
String id;
int val;
RuleType ruleType;
//Newly added field
//int val2 = 0;
public Rule() {}
public Rule(String id, int val, RuleType ruleType) {
this.id = id;
this.val = val;
this.ruleType = ruleType;
//this.val2 = val2;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public RuleType getRuleType() {
return ruleType;
}
public void setRuleType(RuleType ruleType) {
this.ruleType = ruleType;
}
//public int getVal2() {
// return val2;
//}
//public void setVal2(int val2) {
// this.val2 = val2;
//}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Rule rule = (Rule) o;
return val == rule.val && id.equals(rule.id) && ruleType == rule.ruleType;
}
@Override
public int hashCode() {
return Objects.hash(id, val, ruleType);
}
@Override
public String toString() {
return "Rule{" +
"name='" + id + '\'' +
", val=" + val +
", ruleType=" + ruleType +
'}';
}
}
這是規則類型 class
public enum RuleType {
X,
Y,
Z
}
在BroadcastState
中,我正在存儲List<Rule> ruleList;
. 如文檔中所述,我嘗試按照以下步驟檢查架構演變是否適用於此:
啟動flink集群
提交工作 jar
使用flink savepoint <jobId>
命令獲取一個保存點。
停止工作。
修改代碼,在Rule class中增加一個int
字段val2
,如上圖。 新建一個 jar。
嘗試使用flink -s <savepoint>
命令恢復作業。
使用此作業無法重新啟動,因為模式演變失敗並出現以下錯誤:
由以下原因引起:org.apache.flink.util.FlinkException:無法從提供的任何 1 個恢復選項中恢復 CoBroadcastWithNonKeyedOperator_8c5504f305beefca0724b3e55af8ea26_(1/1) 的運算符 state 后端。 at org.apache.flink.streaming.api.operators.BackendRestorerProcedure.createAndRestore(BackendRestorerProcedure.java:160) at org.apache.flink.streaming.api.operators.StreamTaskStateInitializerImpl.operatorStateBackend(StreamTaskStateInitializerImpl.java:286) at org.apache .flink.streaming.api.operators.StreamTaskStateInitializerImpl.streamOperatorStateContext(StreamTaskStateInitializerImpl.java:174)... 11 more Caused by: org.apache.flink.runtime.state.BackendBuildingException: Failed when trying to restore operator state backend at org. apache.flink.runtime.state.DefaultOperatorStateBackendBuilder.build(DefaultOperatorStateBackendBuilder.java:83) at org.apache.flink.runtime.state.hashmap.HashMapStateBackend.createOperatorStateBackend(HashMapStateBackend.java:148) at org.apache.flink.streaming.api.操作 erators.StreamTaskStateInitializerImpl.lambda$operatorStateBackend$0(StreamTaskStateInitializerImpl.java:277) at org.apache.flink.streaming.api.operators.BackendRestorerProcedure.attemptCreateAndRestore(BackendRestorerProcedure.java:168) at org.apache.flink.streaming.api.operators .BackendRestorerProcedure.createAndRestore(BackendRestorerProcedure.java:135)... 13 more Caused by: com.esotericsoftware.kryo.KryoException: Unable to find class: 11 at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java: 138) 在 com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:115) 在 com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:641)
有人可以幫忙嗎? 我懷疑規則 class 出於某種原因沒有被 POJO 序列化程序使用,但我不明白為什么? 它遵循成為 POJO 的所有標准。
這是我經過大量研究后找到的答案。 Flink 文檔在提供示例方面確實很糟糕,因此這可能會幫助其他人解決同樣的問題。
我能夠為這個 class 創建我自己的 TypeInfoFactory,如下所示:
public static class MyPojoTypeInfoFactoryForRule extends TypeInfoFactory<Rule> {
@Override
public TypeInformation<Rule> createTypeInfo(
Type t, Map<String, TypeInformation<?>> genericParameters) {
Map<String, TypeInformation<?>> fields =
new HashMap<String, TypeInformation<?>>() {
{
put("id", Types.STRING);
put("val", Types.INT);
put("ruleType", Types.ENUM(RuleType.class));
put("val2", Types.INT);
}
};
return Types.POJO(Rule.class, fields);
}
}
然后用這個工廠注解Rule class,這樣Rule class就被序列化為一個POJO。
懸而未決的問題是,如何讓它變得更好? 我可以只為枚舉 class 而不是整個規則 class 編寫工廠嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.