Flink写入Cassandra时GenericType<org.apache.flink.types.Row>不支持如何解决
问题原因
该报错是因为Flink无法通过泛型自动推断你转换后的Row流的结构化类型信息,将其识别为无结构的GenericType<Row>,而Flink Cassandra Sink仅支持携带明确类型定义的Row数据流,显式指定Row的类型信息即可解决问题。
修复方案
方案1:在现有转换逻辑基础上补全类型声明
- 首先根据你使用的
AvroSchemaClass的字段定义,构造对应Row的类型信息,字段顺序、字段类型必须和Avro类的定义完全一致,示例如下:
import org.apache.flink.api.common.typeinfo.TypeInformation; import org.apache.flink.api.common.typeinfo.Types; import org.apache.flink.api.java.typeutils.RowTypeInfo; // 按AvroSchemaClass的字段顺序依次填写对应字段的Flink类型 TypeInformation<?>[] fieldTypes = new TypeInformation[]{ Types.LONG, // 第0个字段示例:订单ID Types.STRING, // 第1个字段示例:订单编号 // 依次补全所有字段的类型,直到覆盖Avro类的全部字段 Types.STRING // 第7个字段:对应你用到的country字段 }; RowTypeInfo rowTypeInfo = new RowTypeInfo(fieldTypes);
- 在map算子后调用
returns方法显式指定返回类型,覆盖Flink自动推断的泛型类型:
DataStream<Row> rowInputStream = avroInputStream.map(new MapFunction<AvroSchemaClass, Row>() { @Override public Row map(AvroSchemaClass orders_value) throws Exception { return avroToRow.deserialize(orders_value.toByteBuffer().array()); } }).returns(rowTypeInfo); // 新增该行指定类型
方案2:直接在Kafka消费者层完成Avro到Row的转换(更推荐)
你可以直接将AvroRowDeserializationSchema作为Kafka消费者的反序列化器,省掉多余的map转换步骤,且自带正确的Row类型信息,不会出现类型丢失问题:
// 构造Avro转Row的反序列化器 AvroRowDeserializationSchema avroToRowSchema = new AvroRowDeserializationSchema(AvroSchemaClass.class); // 直接创建输出Row类型的Kafka消费者 FlinkKafkaConsumer010<Row> kafkaConsumer = new FlinkKafkaConsumer010<>(inTopic, avroToRowSchema, properties); // 直接获取携带正确类型信息的Row流 DataStream<Row> rowInputStream = environment.addSource(kafkaConsumer);
内容的提问来源于stack exchange,提问作者phisinger
相关产品推荐
相关产品推荐

