在avro中存储架构有什么好处?

2022-09-01 12:16:01

我们需要序列化一些数据,以便放入solr和hadoop中。

我正在评估相同的序列化工具。

我名单上的前两名是Gson和Avro。

据我所知,Avro = Gson + Schema-In-JSON

如果这是正确的,我不明白为什么Avro在Solr / Hadoop中如此受欢迎?

我在互联网上搜索了很多,但找不到一个正确的答案。

无论它在哪里说,Avro都很好,因为它存储了模式。我的问题是如何处理该架构?

对于Hadoop中非常大的对象来说,这可能是一件好事,其中单个对象存储在多个文件块中,因此将架构与每个部分一起存储有助于更好地分析它。但即使在这种情况下,架构也可以单独存储,只要引用它就足以描述架构。我看不出为什么模式应该成为每个部分的一部分。

如果有人能给我一些很好的用例,Avro如何帮助他们,Gson/Jackson不足以达到这个目的,那将是非常有帮助的。

此外,Avro网站的官方文档说,我们需要给Avro一个模式,以帮助它生成Schema+Data。我的问题是,如果模式是输入的,并且相同的模式与数据的JSON表示一起发送到输出,那么Avro还实现了什么额外的目标?我是否可以通过使用JSON序列化对象,添加我的输入架构并将其称为Avro来自己做到这一点?

我对此感到非常困惑!


答案 1
  1. 不断发展的架构

假设您最初为 Employee 类设计了一个这样的架构

{
{"name": "emp_name", "type":"string"},
{"name":"dob", "type":"string"},
{"name":"age", "type":"int"}
}

后来,您意识到 age 是多余的,并将其从架构中删除。

{
{"name": "emp_name", "type":"string"},
{"name":"dob", "type":"string"}
}

在此架构更改之前序列化和存储的记录呢?您将如何读回这些记录?

这就是 avro 读取器/反序列化程序要求读取器和编写器架构的原因。在内部,它执行架构解析,即。它尝试使旧架构适应新架构。

转到此链接 - http://avro.apache.org/docs/1.7.2/api/java/org/apache/avro/io/parsing/doc-files/parsing.html - “使用操作符号的分辨率”部分

在这种情况下,它确实跳过了操作,即它省略了“年龄”的阅读。它还可以处理字段从 int 到 long 等情况。

这是一篇非常好的文章,解释了模式演变 - http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html

  1. 对于单个文件中的多个记录,架构仅存储一次。

  2. 大小,以极少数字节编码。


答案 2

我认为模式进化解决的关键问题之一在任何地方都没有明确提及,这就是为什么它给新来者带来了如此多的困惑。

一个例子将澄清这一点:

假设一家银行存储了其所有交易的审计日志。日志具有特定的格式,需要存储至少10年。保存这些日志的系统也应该适应这10年中不断发展的格式。

此类条目的架构不会更改太频繁,让我们说平均每年两次,但每个架构都会有大量的条目。如果我们不跟踪架构,那么一段时间后,我们将需要查阅非常旧的代码来找出当时存在的字段,并继续添加if-else语句来处理不同的格式。通过所有这些格式的模式存储,我们可以使用模式演变功能自动将一种格式转换为另一种格式(如果您为它提供较旧和较新的模式,Avro会自动执行此操作)。这样可以避免应用程序在其代码中添加大量 if-else 语句,并且还使其更易于管理,因为我们通过查看存储的架构集(架构通常存储在单独的存储中,数据只有指向其架构的 ID)很容易知道我们拥有的所有格式是什么)。

架构演进的另一个优点是,新格式的生产者可以安全地生成具有新模式的对象,而无需等待下游消费者首先更改。下游使用者可以内置逻辑以简单地挂起处理,除非他们能够看到与新格式关联的新架构。这种自动暂停非常适合保持系统在线并调整新架构的处理逻辑。

因此,总而言之,架构演进通过使用自动格式转换来帮助较新的客户端读取较旧的格式,并且还帮助较旧的客户端以正常的方式暂停处理,直到它们能够理解较新的格式。


推荐