繁体   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