Serialization AVRO模式是否也在二进制部分编码?

Serialization AVRO模式是否也在二进制部分编码?,serialization,deserialization,avro,Serialization,Deserialization,Avro,Avro文件包含纯文本模式,后跟二进制格式的数据。我想知道二进制部分中是否也存在模式(或模式的某些部分)?我有一种预感,模式(或者仅仅是字段名)也会在二进制部分进行编码,因为当我在AVRO文件的普通模式部分进行一些更改时,我会在使用AVRO-tool.jar导出模式时收到一条错误消息。使用二进制编码时,整个文件都使用二进制格式 该文件以一个4字节的头开始,然后紧接着是一个包含一些元数据的映射。此映射包含一个“avro.schema”条目。此项的值是存储为字符串的架构。在地图之后,您将找到您的数据

Avro文件包含纯文本模式,后跟二进制格式的数据。我想知道二进制部分中是否也存在模式(或模式的某些部分)?我有一种预感,模式(或者仅仅是字段名)也会在二进制部分进行编码,因为当我在AVRO文件的普通模式部分进行一些更改时,我会在使用AVRO-tool.jar导出模式时收到一条错误消息。

使用二进制编码时,整个文件都使用二进制格式

该文件以一个4字节的头开始,然后紧接着是一个包含一些元数据的映射。此映射包含一个“avro.schema”条目。此项的值是存储为字符串的架构。在地图之后,您将找到您的数据

如果手动编辑架构,读取并更改其大小,则在该字符串之前存储的长度前缀将不一致,并且文件已损坏

请参阅以了解各种类型是如何进行二进制编码的

我不确定你想要实现什么,我很确定这是不应该实现的。但是为了好玩,让我们试着就地编辑模式

对于本例,我将使用avro源代码树中的
weather.avro
文件:


$java-jar avro-tools-1.8.0.jar getmeta weather-orig.avro
空编解码器
avro.schema{“type”:“record”,“name”:“Weather”,“namespace”:“test”,“fields”:[{“name”:“station”,“type”:“string”},{“name”:“time”,“type”:“long”},{“name”:“temp”,“type”:“int”}],“doc”:“天气读数”。}


$java-jar avro-tools-1.8.0.jar getschema weather-orig.avro
{
“类型”:“记录”,“名称”:“天气”,“命名空间”:“测试”,“文档”:“天气读数”,
“字段”:[
{“名称”:“站”,“类型”:“字符串”},
{“name”:“time”,“type”:“long”},
{“name”:“temp”,“type”:“int”}
]
}


$java-jar/avro-tools-1.8.0.jar tojson weather-orig.avro
{“station”:“011990-99999”,“time”:-619524000000,“temp”:0}
{“station”:“011990-99999”,“time”:-619506000000,“temp”:22}
{“station”:“011990-99999”,“time”:-619484400000,“temp”:-11}
{“电台”:“012650-99999”,“时间”:-65553120000,“临时”:111}
{“station”:“012650-99999”,“time”:-655509600000,“temp”:78}

嗯。这是我们的源文件。简单,两个元数据条目,模式定义了三个字段。现在,我们将尝试了解事物是如何以二进制形式存储的,以及如何编辑文件以更改重命名
站点
int
站点id


$Hextump weather-orig.avro-n 256-C
00000000 4f 62 6a 01 04 14 61 76 72 6f 2e 63 6f 64 65 63 | Obj…avro.codec|
000000 10 08 6e 75 6c 6c 16 61 76 72 6f 2e 73 63 68 65 6d |.null.avro.schem|
0000002061F2027B274797065223A27265636F{“类型”:“记录”|
000000 30 72 64 22 2c 22 6e 61 6d 65 22 3a 22 57 65 61 74 | rd,“名称”:“Weat”|
000000 40 68 65 72 22 2c 22 6e 61 6d 65 73 70 61 63 65 22 |她的“名称空间”|
00000050 3a 22 74 65 74 22 2c 22 66 69 65 6c 64 73 22 |:“测试”,“字段”|
00000060 3a 5b 7b 22 6e 61 6d 65 22 3a 22 73 74 61 69 |:[{“姓名”:“统计|
000000 70 6f 6e 22 2c 22 74 79 70 65 22 3a 22 73 74 72 69 | on,类型:|
00000080 6e 67 22 7d 2c 7b 22 6e 61 6d 65 22 3a 22 74 69 | ng},{“名称”:“ti”|
000000 90 6d 65 22 2c 22 74 79 70 65 22 3a 22 6c 6f 6e 67 | me,“类型”:“长”|
000000 A0 22 7d 2c 7b 22 6e 61 6d 65 22 3a 22 74 65 6d 70 |“},{“名称”:“温度”|
000000 B0 22 2c 22 74 79 70 65 22 3a 22 69 6e 74 22 7d 5d |“,“类型”:“int”}]|
000000 C0 2c 22 64 6f 63 22 3a 22 41 20 77 65 61 74 68 65 |,“文件”:“A|
000000 D0 72 20 72 65 61 64 69 6e 67 2e 22 7d 00 b0 81 b3 | r读数“}|
000000 E0 c4 0a 0c f6 62 fa c9 38 fd 7e 52 00 a7 0a cc 01 |..b..8..R|
000000 F0 18331 39 39 30 2d 39 39 39 39 39 ff a3 90 | 011990-99999|

  • 头四个字节是头
  • 接下来是描述“元数据”映射的第一个块的大小的
    long
    long
    使用可变长度之字形编码,因此这里的
    04
    表示与
    getmeta
    的输出一致的2。(请记住阅读Avro规范以了解各种数据类型的编码方式)
  • 之后,您将找到地图的第一个关键点。键是一个字符串,字符串的前缀是其长度(以字节为单位)。这里的
    0x14
    表示10个字节,这是在UTF-8中编码时“
    avro.codec
    ”的长度
  • 然后可以跳过接下来的10个字节,转到下一个元素。等等。您可以前进,直到找到
    avro.schema
    部分
  • 这个字符串后面是映射值的长度(这是一个字符串,因为它是我们的模式)。这就是您要修改的内容。我们正在将
    站点
    重命名为
    站点id
    ,因此您希望在当前长度上添加3,因此
    f2 02
    现在应该是
    f8 02
    (还记得变长之字形编码吗?)
  • 现在可以更新架构字符串以添加“-id”
  • 享受

java-jar/home/cmathieu/Sources/avro trunk/lang/java/tools/target/avro-tools-1.8.0-SNAPSHOT.jar tojson weather.avro
{“站点id”:“011990-99999”,“时间”:-619524000000,“临时”:0}
{“站点id”:“011990-99999”,“时间”:-619506000000,“临时”:22}
{“站点id”:“011990-99999”,“时间”:-619484400000,“临时”:-11}
{“站点id”:“012650-99999”,“时间”:-65553120000,“临时”:111}
{“站点id”:“012650-99999”,“时间”:-655509600000,“临时”:78}


但正如我所说,您很可能不想这样做。

使用二进制编码时,整个文件都使用二进制格式

该文件以一个4字节的头开始,然后紧接着是一个包含一些元数据的映射。此映射包含一个“avro.schema”条目。此项的值是存储为字符串的架构。在地图之后,您将找到您的数据

如果手动编辑模式,则r