Kafka入门

508 阅读13分钟

image.png

什么是kafka

Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。

Apache Kafka 是一个开源分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用程序。

事件流

介绍

事件流(也叫数据流)是无边界数据集的抽象说法,无边界意味着无限且不断增长,因为随着时间的推移,新数据会不断地到来。

事件流是人体中枢神经系统的数字等价物。

从技术上讲,事件流是从数据库、传感器、移动设备、云服务和软件应用程序等事件源以事件流的形式实时捕获数据的做法; 持久地存储这些事件流以供以后检索; 实时和回顾性地操作、处理和响应事件流; 并根据需要将事件流路由到不同的目标技术。 因此,事件流可确保数据的连续流动和解释,以便正确的信息在正确的时间出现在正确的位置。

特性

  • 有序的。事件的放生总是有先后顺序,如下单后发货
  • 不可变。事件一旦发生,就不能被改变,如下单后取消订单,这样只能重新产生一个新的事件
  • 可重放。数据流是可重播的。

使用场景

  • 实时处理支付和金融交易,例如在证券交易所、银行和保险中。
  • 实时跟踪和监控汽车、卡车、车队和货物,例如物流和汽车行业。
  • 持续捕获和分析来自 IoT 设备或其他设备(例如工厂和风电场)的传感器数据。
  • 收集客户互动和订单并立即做出反应,例如在零售、酒店和旅游行业以及移动应用程序中。
  • 监测住院病人并预测病情变化,以确保在紧急情况下得到及时治疗。
  • 连接、存储和提供公司不同部门产生的数据。
  • 作为数据平台、事件驱动架构和微服务的基础。

kafka作为一个事件流平台,又做了什么?

kafka结合了三个关键功能:

  • 发布-订阅的事件流
  • 持久化和可靠的事件流
  • 在发生时或追溯时处理时间流 所有这些功能都是以分布式高度可扩展弹性容错安全的方式提供的。Kafka 可以部署在裸机硬件、虚拟机和容器上,也可以部署在本地和云端。您可以在自行管理 Kafka 环境和使用各种供应商提供的完全托管服务之间进行选择。

kafka如何工作

Kafka 是一个分布式系统,由通过高性能TCP 网络协议进行通信的服务器和客户端组成。它可以部署在内部和云环境中的裸机硬件、虚拟机和容器上。

服务器:Kafka 作为一个或多个服务器的集群运行,这些服务器可以跨越多个数据中心或云区域。其中一些服务器形成存储层,称为代理。其他服务器运行 Kafka Connect以将数据作为事件流持续导入和导出,从而将 Kafka 与您现有的系统(例如关系数据库以及其他 Kafka 集群)集成。为了让您实现关键任务用例,Kafka 集群具有高度可扩展性和容错性:如果其中任何一个服务器出现故障,其他服务器将接管它们的工作,以确保连续运行而不会丢失任何数据。

客户端:它们允许您编写分布式应用程序和微服务,即使在网络问题或机器故障的情况下,它们也可以并行、大规模和容错方式读取、写入和处理事件流。Kafka 附带了一些这样的客户端,这些客户端通过 Kafka 社区提供的数十个客户端进行了扩充 :客户端可用于 JavaScala,包括更高级别的 Kafka Streams库,用于 GoPythonC/C++ 和许多其他编程语言以及 REST API

主要的概念和术语

事件

事件也被称为记录或消息,事件具有键(key),值(value),时间戳(timestamp)和一些可选的元数据(metadata)标头,事件被组织并持久地存储在主题(Topic)中。

示例:

  • 键:"张三"
  • 值: "给李四了200块钱"
  • 时间戳: "2021年7月8日下午2点26分"

主题(Topic)

Kafka将消息分类,每一类的消息称之为一个主题(Topic)。主题就类似于文件系统中文件夹,事件就是该文件夹中的文件。

生产者(Producer)

生产者是那些向 Kafka 发布(写入)事件的客户端应用程序。

消费者(Consumer)

消费者是订阅(读取和处理)这些事件的那些客户端应用程序。

生产者和消费者之间是完全解耦和不可知的,这是实现 Kafka 高可用和易扩展的关键设计。

分区(Partition)

Kafka 中每个主题(Topic)可以划分多个分区,每个主题(Topic)至少有一个分区,同一个主题(Topic)下的不同分区包含的消息是不同的分区可以间接理解成数据库的分表操作。

服务器(broker):

kafka搭建的集群服务器称为broker,集群中一台服务器可以搭载多个broker

image.png

Kafka的四个核心API

  • Producer API: 发布消息到1个或多个topic中。
  • Consumer API: 订阅一个或多个topic,并处理产生的消息。
  • Streams API: 充当一个流处理器,从1个或多个topic消费输入流,并生产一个输出流到1个或多个输出topic,有效地将输入流转换到输出流。
  • Connector API: 可构建或运行可重用的生产者或消费者,将topic连接到现有的应用程序或数据系统。

image.png

ClientServer之间的通讯,是通过一条简单、高性能并且和开发语言无关的TCP协议。

主题(Topic)和日志(Log)

一个topic可以对应多生产者和多消费者

对于每个topicKafka集群都会维护一个分区log

如下图中所示:

image.png

每一个分区都是一个顺序的、不可变的消息队列, 并且可以持续的添加。分区中的消息都被分了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。

Kafka集群会持久化所有消息,直到它们过期(无论消息是否被消费)。为了保证数据具有容错性和高可用,每个主题(Topic)都可以复制,甚至可以跨区域复制,来保证有多个代理拥有备份,以防万一。

实际上消费者所持有的仅有的元数据就是这个offset(偏移量),也就是说offset由消费者来控制:正常情况当消费者消费消息的时候,偏移量也线性的的增加。但是实际偏移量由消费者控制,消费者可以将偏移量重置为更早的位置,重新读取消息。

image.png

分区的目的

  • 可以处理更多的消息,不受单台服务器的限制。
  • 分区可以作为并行处理的单元

image.png

分布式

Log的分区被分布到集群中的多个服务器上。每个服务器处理它分到的分区。 根据配置每个分区还可以复制到其它服务器作为备份容错。 每个分区有一个leader,零或多个followerLeader处理此分区的所有的读写请求,而follower被动的复制数据。如果leader宕机,其它的一个follower会被推举为新的leader。 一台服务器可能同时是一个分区的leader,另一个分区的follower。 这样可以平衡负载,避免所有的请求都只让一台或者某几台服务器处理。

image.png

生产者(Producers)

生产者往某个Topic上发布消息。生产者也负责选择发布到Topic上的哪一个分区。最简单的方式从分区列表中轮流选择。也可以根据某种算法依照权重选择分区。开发者负责如何选择分区的算法。

消费者(Consumers)

通常来讲,消息模型可以分为两种:

队列

队列的处理方式是 一组消费者从服务器读取消息,一条消息只有其中的一个消费者来处理。

发布-订阅式。

在发布-订阅模型中,消息被广播给所有的消费者,接收到消息的消费者都可以处理此消息。

Kafka为这两种模型提供了单一的消费者抽象模型:消费者组(consumer group)。 消费者用一个消费者组名(groupId)标记自己。

  • 一个发布在Topic上消息被分发给此消费者组中的一个消费者。
  • 假如所有的消费者都在一个组中,那么这就变成了queue模型。 假如所有的消费者都在不同的组中,那么就完全变成了发布-订阅模型。

更通用的, 我们可以创建一些消费者组作为逻辑上的订阅者。每个组包含数目不等的消费者, 一个组内多个消费者可以用来扩展性能和容错。正如下图所示:

image.png

2个kafka集群托管4个分区(P0-P3),2个消费者组,消费组A有2个消费者实例,消费组B有4个。

正如传统的消息系统一样,Kafka保证消息的顺序不变。 传统的队列模型保持消息,并且保证它们的先后顺序不变。但是,尽管服务器保证了消息的顺序,消息还是异步的发送给各个消费者,消费者收到消息的先后顺序不能保证了。这也意味着并行消费将不能保证消息的先后顺序。传统的消息系统中消息的顺序处理很让人头痛。如果只让一个消费者处理消息,又违背了并行处理的初衷。 在这一点上Kafka做的更好,尽管并没有完全解决上述问题。 Kafka采用了一种分而治之的策略:分区。 因为Topic分区中消息只能由消费者组中的唯一一个消费者处理,所以消息肯定是按照先后顺序进行处理的。但是它也仅仅是保证Topic的一个分区顺序处理,不能保证跨分区的消息先后处理顺序。 所以,如果你想要顺序的处理Topic的所有消息,那就只提供一个分区。

注意:相同的消费者组中不能有比分区更多的消费者,否则多出的消费者一直处于空等待,不会收到消息。

Kafka的保证

  • 生产者发送到一个特定的Topic的分区上,消息将会按照它们发送的顺序依次加入,也就是说,如果一个消息M1M2使用相同的producer发送,M1先发送,那么M1将比M2offset低,并且优先的出现在日志中。
  • 消费者收到的消息也是此顺序。
  • 如果一个Topic配置了复制因子(replication factor)为N, 那么可以允许N-1服务器宕机而不丢失任何已经提交(committed)的消息。

Kafka作为一个存储系统

所有发布消息到消息队列和消费分离的系统,实际上都充当了一个存储系统(发布的消息先存储起来)。Kafka比别的系统的优势是它是一个非常高性能的存储系统。

写入到kafka的数据将写到磁盘并复制到集群中保证容错性。并允许生产者等待消息应答,直到消息完全写入。

kafka的磁盘结构 - 无论你服务器上有50KB50TB,执行是相同的。

client来控制读取数据的位置。你还可以认为kafka是一种专用于高性能,低延迟,提交日志存储,复制,和传播特殊用途的分布式文件系统。

kafka的流处理

仅仅读,写和存储是不够的,kafka的目标是实时的流处理。

kafka中,流处理持续获取输入topic的数据,进行处理加工,然后写入输出topic。例如,一个零售APP,接收销售和出货的输入流,统计数量或调整价格后输出。

可以直接使用producerconsumer API进行简单的处理。对于复杂的转换,Kafka提供了更强大的Streams API。可构建聚合计算或连接流到一起的复杂应用程序。

助于解决此类应用面临的硬性问题:处理无序的数据,代码更改的再处理,执行状态计算等。

Sterams APIKafka中的核心:使用producerconsumer API作为输入输出,利用Kafka做状态存储,使用相同的组机制在stream处理器实例之间进行容错保障。

拼在一起

消息传递,存储和流处理的组合看似反常,但对于Kafka作为流式处理平台的作用至关重要。

HDFS这样的分布式文件系统允许存储静态文件来进行批处理。这样系统可以有效地存储和处理来自过去的历史数据。

传统企业的消息系统允许在你订阅之后处理未来的消息:在未来数据到达时处理它。

Kafka结合了这两种能力,这种组合对于kafka作为流处理应用和流数据管道平台是至关重要的。

批处理以及消息驱动应用程序的流处理的概念:通过组合存储和低延迟订阅,流处理应用可以用相同的方式对待过去和未来的数据。它是一个单一的应用程序,它可以处理历史的存储数据,当它处理到最后一个消息时,它进入等待未来的数据到达,而不是结束。

同样,对于流数据管道(pipeline),订阅实时事件的组合使得可以将Kafka用于非常低延迟的管道;但是,可靠地存储数据的能力使得它可以将其用于必须保证传递的关键数据,或与仅定期加载数据或长时间维护的离线系统集成在一起。流处理可以在数据到达时转换它。