【问题标题】:Avro serialization: How does the length of keys effect the size of data after serialisation as byte array?Avro 序列化:键的长度如何影响序列化为字节数组后的数据大小?
【发布时间】:2020-08-20 09:25:23
【问题描述】:

我创建了两个 Avro 模式,一个有短键,另一个有长键。我将相同的数据放在它们上面,并将它们序列化为byte array。 然后,我检查了长度,它是一样的。

如果不影响数据的大小,那么key是如何保存的呢?

我测试过的架构:

{
"namespace": "namespace",
 "type": "record",
 "name": "TestA",
 "fields": [
     {"name": "dataFieldIsVeryVeryVeryLong", "type": "string"},
     {"name": "dataField2IsVeryVeryVeryVerylong", "type": ["null", "string"], "default": null}
     ]
}

{
"namespace": "namespace",
 "type": "record",
 "name": "TestB",
 "fields": [
     {"name": "s", "type": "string"},
     {"name": "ss", "type": ["null", "string"], "default": null}
     ]
}

【问题讨论】:

    标签: serialization deserialization avro


    【解决方案1】:

    没有保存键,avro 序列化基于字段的类型和顺序工作。在您的情况下,您使用:

    • 记录 - 它是字段的串联
    • 字符串长度较长,然后是UTF-8字符编码
    • 两种类型的联合,它有 int 来指定它是哪种类型,然后它使用这种类型编码

    对于这个值:

    {
        "s": "qwe",
        "ss": null
    }
    

    十六进制编码将是06 71 77 65 00 - 我们知道这是一条记录,所以我们使用字段编码。 first 是一个字符串,对于一个字符串 first 是一个长度,06 是一个 long 3 的 avro 编码,所以接下来的 3 个值是一个字符串内容。如果您搜索具有十六进制值的 ASCII 表,您将看到 71 是 q,77 是 w,65 是 e。 下一个字段是 union,所以 encoding 对于哪个类型有 int,00 是 int 0 的 avro 编码,所以首先在 union 中输入。在您的情况下,这是“null”,null 被编码为无字节,因此这是数据的结尾。如果是02,则意味着在位置 1 上键入 - 架构中的字符串,然后会跟随字符串值的编码。

    您可以在documentation阅读更多相关信息

    如果你想看更多的例子,我写了一个post关于它

    【讨论】:

    • 那么,我们是否推断如果我们存储一个字节序列化的 avro,并将数据存储在某个地方,无论是某个数据库还是消息队列,它会比 JSON 或 JSONString、Map 之类的东西消耗更少的空间(或者基本上是任何键值对模式)?
    • 这个不好回答。值的二进制编码应该更小,也许如果你对 JSON 使用了一些压缩,它的大小可能会相对较小。问题是您如何存储架构。如果您使用类似 Schema Registry 之类的东西,那么您将必须在您的消息中存储一个 id (int)。如果您决定为每条消息存储一个模式,它将占用更多空间。 Avro、Protobuf 和 Thrift 为您提供模式演变,这在更改以后的数据格式时非常有用。存储相对便宜,尤其是与人力/维护成本相比。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 2017-07-08
    • 2012-03-09
    相关资源
    最近更新 更多