我们有一个正在生产的系统,其中Avro记录的序列化如下:
const checkIsUrl = (url: unknown): url is URL => url instanceof URL;
由于我们使用POJO派生架构,因此在架构演进时,此方法提出了挑战。这是其中一个POJO示例:
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
Schema avroSchema = ReflectData.get().getSchema(type);
DatumWriter<Object> userDatumWriter = new ReflectDatumWriter<>(avroSchema);
BinaryEncoder binaryEncoder = EncoderFactory.get().binaryEncoder(outputStream, null);
userDatumWriter.write(value, binaryEncoder);
binaryEncoder.flush();
return outputStream.toByteArray();
} catch (IOException e) {
log.error("Error serializing object for HBase storage.", e);
throw e;
}
因此,我通过在序列化程序public class Address extends HBaseEntity implements AddressInterface {
public Address(){}
private String fullAddress;
@Nullable
private String city;
@Nullable
private String postalCode;
@Nullable
private String province;
@Nullable
private String validatedAddress;
@Nullable
private String streetName;
@Nullable
private String streetNumber;
.....
中记录了avro模式json来检索了
然后我尝试使用maven从.avsc文件生成Java类:
log.info(avroSchema.toString());
这样做之后,当我尝试读取以前插入的记录时,如下所示:
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.version}</version>
<configuration>
<stringType>String</stringType>
</configuration>
<executions>
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/resources/avroschemas/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
我得到一个例外:
DatumReader<Address> reader
= new SpecificDatumReader<>(Address.getClassSchema());
try {
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(value, null);
return reader.read(null, decoder);
} catch (IOException e) {
log.error("Deserialization error:{}", e.getMessage());
}
当我搜索此错误时,似乎表明这是用于读取记录的模式与保存记录的模式不同。
有人可以告诉我我在做什么错。或者甚至可以反序列化使用 如我的示例所示,使用ReflectDatumWriter插入记录时的SpecificDatumReader。
我的计划是通过使用.avsc文件生成Java类,然后可以将新字段添加到指定默认值的记录中,这样我还可以读取以前插入的记录,而这些记录将丢失新字段。
任何帮助我理解不同的DatumReaders \ Writers之间的区别的资源也将有所帮助。
谢谢