Kafka使用Avro序列化data

       如果您正开始使用Kafka,那么您需要做的一件事就是选择一种数据格式。最重要的是在使用过程中保持一致。任何格式,无论是XML、JSON还是ASN.1,如果它在所有领域都得到一致的使用,那么它总比一堆乱七八糟的临时选择要好。
       但如果你是从头开始使用Kafka,哪一种格式最好?这里有许多标准:效率、易用性、对不同编程语言的支持,等等。在我们自己的使用中,我们发现Apache Avro是流数据更好的选择之一。
       Avro有一个类似JSON的数据模型,但可以表示为JSON或紧凑的二进制形式。它提供了一种非常复杂的模式描述语言来描述数据。
       我们认为Avro是最好的选择,原因如下:
(1)它可以直接从json映射,或直接映射为json格式。
(2)拥有非常紧凑的格式。
(3)非常快。
(4)它为各种编程语言提供了强大的绑定,因此可以生成更容易处理事件数据的Java对象,但不需要生成代码,因此可以为任何数据流编写通用的工具。
(5)它有一个用纯JSON定义的丰富的、可扩展的模式语言。

       尽管处理这种元数据似乎是一件小事,但事实证明,在保持数据的高质量和易于在组织范围内使用方面,处理这种元数据是最关键和最不受重视的方面之一。

       Avro的一个关键特性是能够为数据定义模式。例如,代表产品销售的事件可能是这样的:

{
  "time": 1424849130111,
  "customer_id": 1234,
  "product_id": 5678,
  "quantity":3,
  "payment_type": "mastercard"
}

       它可能有这样一个schema,它定义了这五个字段:

{
  "type": "record",
  "doc":"This event records the sale of a product",
  "name": "ProductSaleEvent",
  "fields" : [
    {"name":"time", "type":"long", "doc":"The time of the purchase"},
    {"name":"customer_id", "type":"long", "doc":"The customer"},
    {"name":"product_id", "type":"long", "doc":"The product"},
    {"name":"quantity", "type":"int"},
    {"name":"payment",
     "type":{"type":"enum",
         "name":"payment_types",
             "symbols":["cash","mastercard","visa"]},
     "doc":"The method of payment"}
  ]
}

       下面介绍如何使用这些schema。你将把这样的schema与每个Kafka topic关联起来。你可以将该schema想象成关系数据库表的schema,给出生成到topic中的数据的需求,以及如何从topic读取数据的说明。
       这些schema最终服务于许多关键地点:
(1)它们让数据流的生产者或消费者知道事件中需要哪些字段,以及每个字段的类型。
(2)They document the usage of the event and the meaning of each field in the “doc” fields.
(3)它们保护下游数据消费者不受脏数据的影响,因为主题中只允许有效数据。

       当只有一个数据主题和一个应用程序进行读写时,schema的价值就不那么明显了。然而,当关键数据流在系统中流动,数十或数百个系统依赖于此时,简单的数据推理工具就会产生巨大的影响。
       但是首先,您可能会问为什么我们需要schema?现代的大数据世界不都是关于非结构化数据的吗?以任何方便的形式转储数据,然后在查询数据时进行解析?

为什么需要Schemas

       我认为,如果正确地使用模式,那么它将是一个巨大的福音,可以保持数据的整洁,并使每个人都更加敏捷。对模式的许多反应来自两个因素——关系数据库中的历史限制,这使得模式更改变得困难;以及许多现代分布式基础设施的不成熟,这些基础设施还没有时间完成语义层的建模。
       下面是schemas的一些示例。

鲁棒性

       这种将数据建模为流的体系结构的主要优点之一是应用程序是解耦的。应用程序生成一个事件流,在不知道订阅这些流的对象的情况下捕捉发生的事件。
       但在这样一个世界里,你怎么能推理出数据的正确性呢?在没有任何实际schema的情况下,数据流的新生成程序将尽力模仿现有数据,但是会出现不一致的情况——某些神奇的字符串常量不会被一致地复制,重要的字段会被忽略,等等。

清晰

       更糟糕的是,数据的实际含义变得模糊,而且常常被不同的应用程序误解,因为没有关于字段含义的真正规范文档。一个人以一种方式解释一个字段并相应地填充它,另一个人以不同的方式解释它。
       通常情况下,最终会得到一种非正式的白话“模式”,通过wiki或电子邮件在用户之间传递数据,但如果没有更新这种定义,这种schema就会被丢弃。我们发现缺乏文档会导致人们猜测字段的含义,当猜测错误时,这不可避免地会导致错误和错误的数据分析。

兼容性

       模式还有助于解决组织范围的数据流中最困难的问题之一:对数据格式的更改进行建模和处理。schema在某个时间点定义,但数据需要随着业务和代码的发展而发展。总是会有新的字段、数据表示方式的更改或新的数据流。这是数据库通常忽略的问题。数据库表的所有行都有一个schema。但是,如果您编写的许多应用程序都在不同的时间发生变化并进行schema的演化,那么这种严格的定义就无法工作。如果有几十个应用程序都使用一个中央数据流,那么它们就不能同时更新。、
       随着越来越多的人使用这些数据以及不同数据流的数量的增加,管理这些更改变得更加复杂。当然,添加一个新字段是安全的更改,但是删除一个字段是安全的的吗?重命名已存在的field呢?将字段从字符串更改为数字呢?
       Hadoop可以使用Avro或列式存储文件格式(如Parquet或ORC)“按原样”加载数据。因此,可以非常自动地从数据流加载数据,但是当格式发生变化时会发生什么呢?是否需要重新处理所有历史数据以将其转换为新格式?当涉及到数百tb的数据时,这可能是相当大的工作量。您如何知道给定的更改是否需要这样做?
       schema使Hadoop或Cassandra等具有灵活数据格式的系统能够跟踪上游数据更改,并简单地将这些更改传播到自己的存储中,而无需昂贵的重新处理。Schemas提供了一种机制,用于推断哪些格式更改是兼容的(因此不需要重新处理),哪些是不兼容的。
       我们发现,大多数实现了大型流平台而没有schema控制数据正确性的人都导致了严重的规模不稳定。在与Kafka这样的系统一起使用时,这些兼容性破坏通常是特别痛苦的,因为事件的生产者甚至可能不知道所有的使用者,所以手动测试兼容性可能很快就变得不可能。

你可能感兴趣的:(Kafka使用Avro序列化data)