kafka:(6) 构建数据管道

  在使用 Kafka 构建数据管道时,通常有两种使用场景 : 第一种,把 Kafka 作为数据管道的两个端点之一 ,例如,把 Kafka 里的数据移动到 S3 上,或者把 MongoDB 里的数据移动
到 Kafka 里;第二种,把 Kafka 作为数据管道两个端点的中间媒介,例如,为了把 Twitter的数据移动到 ElasticSearch 上,需要先把它们移动到 Kafka 里,再将它们从 Kafka 移动到
Elastic Search 上 。
  Kafka 为数据管道带来的主要价值在于,它可以作为数据管道各个数据段之间的大型缓冲区, 有效地解桐管道数据的生产者和消费者。 Kafka 的解藕能力以及在安全和效率方面的
可靠性 ,使它成为构建数据管道的最佳选择。

一、构建数据管道时需要考虑的问题

1、及时性

  有些系统希望每天一次性地接收大量数据,而有些则希望在数据生成几毫秒之内就能拿到它们。Kafka 作为一个基于流的数据平台,提供了可靠且可伸缩的数据存储,可以支持几近实时的数据管道和基于小时的批处理。生产者可以频繁地向 Kafka 写入数据,也可以按需写入:消费者可以在数据到达的第一时间读取它们,也可以每隔一段时间读取一次积压的数据。

2、可靠性

  我们要避免单点故障,并能够自动从各种故障中快速恢复。有些系统允许数据丢失,不过在大多数情况下,它们要求至少一次传递。也就是说,源系统的每一个事件都必须到达目的地,不过有时候需要进行重试,而重试可能造成重复传递。有些系统甚至要求仅一次传递一一源系统的每一个事件都必须到达目的地,不允许丢失,也不允许重复 。Kafka 本身就支持“至少一次传递”,如果再结合具有事务模型或唯一键特性的外部存储系统,Kafka 也能实现“仅一次传递”。
Connect APl 为集成外部系统提供了处理偏移量的 APl ,连接器因此可以构建仅一次传递的端到端数据管道 。

3、高吞吐量和动态吞吐量

  为了满足现代数据系统的要求,数据管道需要支持非常高的吞吐量。更重要的是,在某些情况下,数据管道还需要能够应对突发的吞吐量增长。由于我们将 Kafka 作为生产者和消费者之间的缓冲区,消费者的吞吐量和生产者的吞吐量就不会耦合在一起了。我们也不再需要实现复杂的回压机制,如果生产者的吞吐量超过了消费者的吞吐量,可以把数据积压在 Kafka 里,等待消费者追赶上来。通过增加额外的消费者或生产者可以实现 Kafka 的伸缩,因此我们可以在数据管道的任何一边进行动态的伸缩,以便满足持续变化的需求。
  因为 Kafka 是一个高吞吐量的分布式系统,一个适当规模的集群每秒钟可以处理数百兆的数据,所以根本无需担心数据管道无法满足伸缩性需求。另外 ,Connect API 不仅支持伸缩,而且擅长并行处理任务。

4、数据格式

  数据管道需要协调各种数据格式和数据类型,这是数据管道的一个非常重要的因素。

5、转换

  数据管道的构建可以分为两大阵营,即 ETL 和 ELT。
  ETL 表示提取一转换一加载,当数据流经数据管道时,数据管道会负责处理它们。这种方式为我们节省了时间和存储空间,因为不需要经过保存数据、修改数据、再保存数据这样的过程,但数据的转换会给数据管道下游的应用造成一些限制,特别是当下游的应用希望对数据进行进一步处理的时候。
  ELT 表示提取-加载-转换 。在这种模式下,数据管道只做少量的转换(主要是数据类型转换),确保到达数据池的数据尽可能地与数据源保持一致。 目标系统收集“原始数据”,并负责处理它们。这种方式为目标系统的用户提供了最大的灵活性,因为它们可以访问到完整的数据。这种方式的不足在于,数据的转换占用了目标系统太多的 CPU 和存储资源。

6、安全性

  Kafka 支持加密传输数据,从数据源到 Kafka ,再从 Kafka 到数据池。它还支持认证(通过SASL 来实现)和授权,所以你可以确信,如果一个主题包含了敏感信息,在不经授权的情况下,数据是不会流到不安全的系统里的。

7、故障处理能力

  因为 Kafka 会长时间地保留数据,所以我们可以在适当的时候回过头来重新处理出错的数据 。

8、耦合性和灵活性

  数据管道最重要的作用之一是解耦数据源和数据池。

二、Kafka Connect

  Connect 可以用于从外部数据存储系统读取数据,或者将数据推送到外部存储系统。
  Connect 是 Kafka 的一部分,它为在 Kafka 和外部数据存储系统之间移动数据提供了一种可靠且可伸缩的方式。Connect 以 worker 进程集群的方式运行,我们基于 worker 进程安装连接器插件,然后使用 REST API 来管理和配置 connector,这些 worker 进程都是长时间持续运行的作业。连接器启动额外的 task ,有效地利用工作节点的资源,以并行的方式移动大量的数据。数据源的连接器负责从源系统读取数据,并把数据对象提供给 worker 进程。数据池的连接器负责从worker 进程获取数据,并把它们写入目标系统。

1、连接器和任务

  连接器:负责以下 3 件事情。

  • 决定需要运行多少个任务。
  • 按照任务来拆分数据复制。
  • 从 worker 进程获取任务配置并将其传递下去。例如,JDBC 连接器会连接到数据库,统计需要复制的数据表,并确定需要执行多少个任务,然后在配置参数 max.tasks和实际数据量之间选择数值较小的那个作为任务数。在确定了任务数之后,连接器会为每个任务生成一个配置,配置里包含了连接器的配置项和该任务需要复制的数据表。worker 进程负责启动和配置任务,每个任务只复制配置项里指定的数据表。如果通过REST API 启动连接器,有可能会启动任意节点上的连接器,那么连接器的任务就会在该节点上执行。

  任务:负责将数据移入或移出 Kafka。任务在完成初始化之后,就开始按照连接器指定的配置启动工作。 源系统任务对外部系统进行轮询,并返回一些记录,worker 进程将这些记录发送到 Kafka。数据池任务通过 worker 进程接收来自 Kafka 的记录 ,并将它们写入外部系统。

2. worker 进程

  worker 进程是连接器和任务的“容器”。它们负责处理 HTTP 请求,这些请求用于定义连接器和连接器的配置。它们还负责保存连接器的配置、启动连接器和连接器任务,并把配置信息传递给任务。如果一个 worker 进程停止工作或者发生崩溃,集群里的其他 worker进程会感知到( Kafka 的消费者协议提供了心跳检测机制),并将崩溃进程的连接器和任务重新分配给其他进程。如果有新的进程加入集群,其他进程也会感知到,并将自己的连接器和任务分配给新的进程,确保工作负载的均衡。进程还负责提交偏移量,如果任务抛出异常,可以基于这些偏移量进行重试。
  为了更好地理解 worker 进程,我们可以将其与连接器和任务进行简单的比较。连接器和任务负责“数据的移动”, 而 worker 进程负责 REST API、配置管理、可靠性、高可用性、伸缩性和负载均衡。

3. 转化器和 Connect 的数据模型

  源连接器所做的事情都很相似一一从源系统读取事件,并为每个事件生成schema 和值(值就是数据对象本身) 。目标连接器正好相反,它们获取 schema 和值,并使用 schema 来解析值,然后写入到目标系统。
  源连接器只负责基于 Data API 生成数据对象,那么 worker 进程是如何将这些数据对象保存到 Kafka 的?这个时候,转换器就派上用场了。用户在配置 worker 进程(或连接器)时可以选择使用合适的转化器,用于将数据保存到Kafka。连接器通过 Data API 将数据返回给 worker 进程,worker 进程使用指定的转化器将数据转换成 Avro 对象、JSON 对象或者字符串,然后将它们写入 Kafka 。
  对于目标连接器来说,过程刚好相反一一在从 Kafka 读取数据时,worker 进程使用指定的转换器将各种格式( Avro 、 JSON 或 String)的数据转换成 Data API 格式的对象,然后将它们传给目标连接器,目标连接器再将它们插入到目标系统。

4. 偏移量管理

  源连接器返回给 worker 进程的记录里包含了一个逻辑分区和一个逻辑偏移量。它们并非Kafka 的分区和偏移量,而是源系统的分区和偏移量。在设计一个源连接器时,要着重考虑如何对源系统的数据进行分区以及如何跟踪偏移量,这将影响连接器的并行能力,也决定了连接器是否能够实现至少一次传递或者仅一次传递。
  源连接器返回的记录里包含了源系统的分区和偏移量, worker 进程将这些记录发送给Kafka 。如果 Kafka 确认记录保存成功,worker 进程就把偏移量保存下来。偏移量的存储机制是可插拔的,一般会使用 Kafka 主题来保存。如果连接器发生崩溃并重启,它可以从最近的偏移量继续处理数据。
  目标连接器的处理过程恰好相反,不过也很相似。它们从 Kafka 上读取包含了主题、分区和偏移量信息的记录,然后调用连接器的 put() 方法,该方法会将记录保存到目标系统里。如果保存成功,连接器会通过消费者客户端将偏移量提交到 Kafka 上。

原文地址:https://www.cnblogs.com/zjxiang/p/15414520.html