簡體   English   中英

Flink 模式演變不適用於廣播 state

[英]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; . 如文檔中所述,我嘗試按照以下步驟檢查架構演變是否適用於此:

  1. 啟動flink集群

  2. 提交工作 jar

  3. 使用flink savepoint <jobId>命令獲取一個保存點。

  4. 停止工作。

  5. 修改代碼,在Rule class中增加一個int字段val2 ,如上圖。 新建一個 jar。

  6. 嘗試使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM