我们需要序列化一些数据以放入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来自行完成?
我真的很困惑!
答案 0 :(得分:8)
假设你为Employee类设计了一个这样的模式
{
{"name": "emp_name", "type":"string"},
{"name":"dob", "type":"string"},
{"name":"age", "type":"int"}
}
后来你意识到年龄是多余的,并将其从架构中删除。
{
{"name": "emp_name", "type":"string"},
{"name":"dob", "type":"string"}
}
在此架构更改之前序列化和存储的记录如何?你将如何回读这些记录?
这就是avro reader / deserializer要求读写器架构的原因。在内部,它执行模式解析,即。它试图使旧模式适应新模式。
转到此链接 - 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 :(得分:5)
我认为模式演变解决的关键问题之一并没有明确提及,这就是为什么它会给新来者带来如此多的混乱。
一个例子将澄清这一点:
让我们说银行存储其所有交易的审计日志。日志具有特定格式,需要存储至少10年。持有这些日志的系统也应该适应这10年中不断发展的格式。
此类条目的模式不会经常更改,让我们平均每年说两次,但每个模式都会有大量条目。如果我们不跟踪模式,那么过了一段时间,我们需要查阅非常旧的代码来找出当时存在的字段,并继续添加if-else语句来处理不同的格式。使用所有这些格式的模式存储,我们可以使用模式演化功能自动将一种格式转换为另一种格式(如果您使用较旧和较新的模式,Avro会自动执行此操作)。这样可以避免应用程序在代码中添加大量if-else语句,并使其更易于管理,因为我们通过查看存储的模式集来了解所有格式(模式通常存储在单独的存储中,数据只有一个指向其架构的ID。
模式演变的另一个优点是新格式的生成者可以安全地生成具有新模式的对象,而无需等待下游消费者首先进行更改。下游消费者可以拥有内置的逻辑来简单地暂停处理,除非他们能够看到与新格式相关联的新模式。这种自动暂停非常适合保持系统在线并适应新架构的处理逻辑。
总而言之,模式演化通过使用自动格式转换帮助较新的客户端读取较旧的格式,并帮助较旧的客户端以优雅的方式暂停处理,直到它们能够理解更新的格式。