介绍

Kafka简介

Kafka是一种分布式的,基于发布/订阅的消息系统。主要设计目标如下:

  • 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。

  • 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。

  • 支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输。

  • 同时支持离线数据处理和实时数据处理。

  • 支持在线水平扩展。

为何使用消息系统

  • 解耦

    在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。

  • 冗余

    有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。

  • 扩展性

    因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。

  • 灵活性 & 峰值处理能力

    在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

  • 可恢复性

    系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

  • 顺序保证

    在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。Kafka保证一个Partition内的消息的有序性。

  • 缓冲

    在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行———写入队列的处理会尽可能的快速。该缓冲有助于控制和优化数据流经过系统的速度。

  • 异步通信

    很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

Apache kafka是一个分布式流媒体平台。这到底是什么意思呢?

一个流媒体平台应具有三个关键能力:

  1. 它可以让你发布和订阅的记录流。在这方面,它类似于一个消息队列或企业信息系统。

  2. 它可以让你存储的记录中的流容错方式。

  3. 它可以让他们出现您处理的记录流。

什么场景下使用Kafka?

它被用于两大类应用:

  1. 建立实时流数据管道不仅能够可靠地获得系统或应用程序之间的数据。

  2. 构建实时流式变换或反应数据流应用。

kafka 相关概念

首先确定几个概念:

  • Message: 消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息。

  • Broker: Kafka集群包含一个或多个服务器,这种服务器被称为broker。

  • Topic: 每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic,在其他消息队列系统里面叫做队列名。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)

  • Partition: Partition是物理上的概念,每个Topic包含一个或多个Partition。

  • Producer: 消息生产者,发布消息到 kafka 集群的终端或服务。

  • Consumer:消息消费者,向Kafka broker读取消息的客户端。

  • Consumer group:high-level consumer API 中,每个 consumer 都属于一个 consumer group,每条消息只能被 consumer group 中的一个 Consumer 消费,但可以被多个 consumer group 消费。(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

  • kafka运在一个或多个服务器集群。

  • 在被称为主题类别的kafka集群存储的记录流。

  • 每个记录包含一个键,值和时间戳。

kafka有四个核心API:

  • 生产者API允许应用程序发布的记录流至一个或多个kafka的topic。

  • 消费者API允许应用程序订阅一个或多个主题,并处理所产生的对他们记录的数据流。

  • 流API允许应用程序充当流处理器从一个或多个主题消耗的输入流,并产生一个输出流至一个或多个输出的主题,有效地变换所述输入流,以输出流。

  • 连接器API允许构建和运行kafka topic连接到现有的应用程序或数据系统中重用生产者或消费者。例如,一个连接到关系数据库可能会捕捉每一个变化表。

kafka apis

在kafka的客户端和服务器之间的通信是一个简单的,高性能的,与语言无关的TCP协议来完成。此协议版本,并保持向后兼容旧版本的兼容性。我们对kafka提供了一个Java客户端,但是客户端有多种语言可供选择。

Kafka的架构:

kafka apis

Kafka的整体架构非常简单,是显式分布式架构,producer、broker(kafka)和consumer都可以有多个。Producer,consumer实现Kafka注册的接口,数据从producer发送到broker,broker承担一个中间缓存和分发的作用。
broker分发注册到系统中的consumer。broker的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存。客户端和服务器端的通信,是基于简单,高性能,且与编程语言无关的TCP协议。

消息发送的流程:

kafka apis

  1. Producer根据指定的partition方法(round-robin、hash等),将消息发布到指定topic的partition里面。

  2. kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被消费。

  3. Consumer从kafka集群pull数据,并控制获取消息的offset。

Kafka的设计:

1、吞吐量

高吞吐是kafka需要实现的核心目标之一,为此kafka做了以下一些设计:

1、数据磁盘持久化:消息不在内存中cache,直接写入到磁盘,充分利用磁盘的顺序读写性能;

2、zero-copy:减少IO操作步骤;

3、数据批量发送;

4、数据压缩;

5、Topic划分为多个partition,提高parallelism;

2、负载均衡

1、producer根据用户指定的算法,将消息发送到指定的partition;

2、存在多个partiiton,每个partition有自己的replica,每个replica分布在不同的Broker节点上;

3、多个partition需要选取出lead partition,lead partition负责读写,并由zookeeper负责fail over;

4、通过zookeeper管理broker与consumer的动态加入与离开;

3、拉取系统

由于kafka broker会持久化数据,broker没有内存压力,因此,consumer非常适合采取pull的方式消费数据,具有以下几点好处:

1、简化kafka设计;

2、consumer根据消费能力自主控制消息拉取速度;

3、consumer根据自身情况自主选择消费模式,例如批量,重复消费,从尾端开始消费等;

4、可扩展性

1、当需要增加broker结点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化,并及时作出调整。

Topics and Logs(主题和日志)

让我们先潜入核心抽象kafka提供了记录,该主题的流。

Topic是作为一类消息名称记录被公布。在kafka的Topic始终是多用户;也就是说,一个Topic可以有零个,一个或多个消费者订阅写入的数据。

对于每一个主题,Topic集群保持分区日志,看起来像这样:

kafka apis

每个分区是记录一个有序的,一成不变的序列不断追加到一个结构化的提交日志。

在分区中的记录是调用的每个分配的序列ID号的偏移量唯一地标识该分区中的每个记录。

kafka集群保留所有发布的记录,不论其是否具有可配置的保留期限被使用或消费。例如,如果将保留策略设置为两天,然后记录公布后两天,它可用于消费,之后它将被丢弃以腾出空间。kafka的性能相对于数据的大小实际上不变,以便将数据存储很长一段时间是没有问题的。

kafka apis

事实上,保留在每个消费者基础的唯一的元数据是在日志中,消费者的偏移或位置。这种偏移是由消费者控制:通常消费者会促进其线性偏移,因为它读取记录,但事实上,因为其位置是由消费者可以在任何它喜欢的顺序消耗记录进行控制。例如,消费者可以恢复到旧的偏移量从过去的数据再加工或者直接跳到最新的记录,并开始从“现在”消费。

这些功能的结合意味着,kafka的消费者都是很便宜的,他们可以来去无集群上或其他消费者产生太大影响。例如,你可以使用我们的命令行工具“tail”的任何话题,而无需改变什么是任何现有的消费者消费的内容。

日志中的分区,一举数得。首先,它们允许日志扩展到超过一个的大小,将适合在单个服务器上。每个单独的分区必须适合承载它的服务器上,但一个话题可能有很多分区,以便它能够处理任意的数据量。其次,他们作为并行性更上一个位的单位。

Distribution(分布式)

日志的分区分布在每台服务器处理数据和请求对分区的份额kafka集群中的服务器。每个分区跨容错服务器配置数量的复制。
每个分区有它充当“leader”和零个或多个服务器充当“followers”一台服务器。领导者处理所有的读取和写入分区的要求而被动的追随者复制的领导者。如果领导者失败了,追随者之一将自动成为新的领导者。每个服务器充当一些分区,而对其他跟随的领导者这样的负载是在集群内均衡。

Producers(生产者)

生产者数据发布到他们所选择的主题。制片人负责选择分配哪些记录在主题中哪个分区。这可以在一个循环的方式进行简单地平衡负载,也可以根据一些语义分区功能(比如基于记录一些关键)来完成。更多关于在第二使用分区!

Consumers(消费者)

消费者标榜自己与消费者的组名,并发布到一个话题每个记录每个订阅用户组内交付给消费者的一个实例。消费实例可以在单独的进程或单独的机器上。
如果所有的消费者实例具有相同的消费群,那么记录将有效地加载在消费者实例平衡。
如果所有的消费者实例有不同的消费群体,那么每个记录将被广播到所有的消费过程。

kafka apis

两个服务器集群kafka举办两个消费群体的四个分区(P0-P3)。一个消费群体有两个消费情况与B组有四个。
更常见的,但是,我们已经发现,主题有一个小的消费群体,每一个“逻辑用户”的。每组都是由可扩展性和容错许多消费者实例。这只不过是发布 - 订阅语义在那里用户是消费者,而不是一个单一的过程中群集的更多。
消费kafka的实现方式是通过将建立分区日志在Consumer实例,使每个实例是分区的“公平份额”的在任何时间点的独家消费者。维持组中的成员的这个过程是通过动态kafka协议处理。如果新的实例加入该组,他们将接管从该组的其他成员一些分区;如果一个实例死亡,其分区将被分配到剩余的实例。
kafka只提供了记录的总订单分区中,而不是一个主题的不同分区之间。每个分区的顺序与键对数据进行分区的能力相结合足以满足大多数应用。但是,如果在记录总共需要为了这个可以与只有一个分区的主题实现的,虽然这将意味着只有一个每个消费群体的消费过程。

kafka 作为一个消息系统

如何流的kafka的观念比较传统的企业信息系统?
消息历来有两种模型:队列和发布 - 订阅。在队列中,消费者的池可以从服务器读取和记录每一个进入其中的一个;在发布 - 订阅记录被广播到所有的消费者。每个这两种模式具有一定的实力和弱点。排队的优点是它可以让你瓜分了数据在多个消费情况的处理,它可以让您扩展您的处理。不幸的是,队列不是多用户,一旦一个进程读取它不见了数据。发布 - 订阅模式可以让你广播数据到多个进程,但没有,因为每一个消息发送到每个用户的缩放处理的方式。
在kafka的消费群的概念推广这两个概念。与队列的消费群让你过的进程的集合(消费群的成员)瓜分处理。与发布 - 订阅,kafka让您发送广播消息到多个消费群体。
kafka的模型的优点是,每个主题都有两个属性,它可以扩展的处理,也是多用户,有没有必要选择一个或另一个。
kafka具有较强的排序保证比传统的消息系统了。
传统的队列保留在服务器上,订单记录,如果多个消费者从队列中消耗那么服务器双手出存储它们的订单记录。然而,尽管服务器为了捧出来的记录,这些记录被异步传递给消费者,让他们可以在不同的消费者到达的顺序。这实际上意味着记录的排序在并行消费的存在都将丢失。消息系统通常解决这个具有“排他性消费”,只允许一个过程从队列中消耗的概念,当然,这意味着有正在处理的并行性。
kafka做的更好。通过具有一个概念并行性的分区中的主题,kafka是能够通过消费者的进程池同时提供排序保证和负载平衡。这是通过使每个分区由该组中只有一个消费者所消耗的话题,消费者的消费群在指定的分区来实现的。通过这样做,我们确保消费者的是,分区唯一的读者,为了消耗数据。因为有许多的分区,这还是平衡了许多消费者的情况下的负载。但是请注意,不能在一个消费群体比分区的详细消费情况。

kafka 作为一个存储系统

任何消息队列,它允许从消费他们解耦出版消息被有效地充当用于在飞行中消息的存储系统。这就是kafka与其他消息队列系统不同的地方,因为它是一个很好的存储系统。
写到kafka数据写入到磁盘和复制的容错。kafka允许生产者在确认等待,以便不被认为是写操作完成,直到它被完全复制,并保证持续下去,即使写入服务器失败。
磁盘结构kafka使用很好地扩展,kafka将执行相同的你是否有50 KB或服务器上的持久性数据的50 TB。
由于把存储的重视,并允许客户控制自己的读取位置的结果,你能想到kafka作为一种特殊用途的分布式文件系统,致力于高性能,低延迟提交日志存储,复制和传播。

kafka 流处理

这是不够的,只是读,写,以及数据的储存流,目的是使数据流的实时处理。
在kafka流处理器是任何需要从输入的主题数据的连续流,该输入执行一些处理,并产生数据的连续流,以输出主题。
例如,零售应用程序可能需要在销售和出货量和输出的输入流计算关闭此数据重新排序和价格调整的流。
这是可以做到的简单处理直接使用生产者和消费者的API。然而,对于更复杂的转换kafka提供了一个完全集成的流API。这允许做不平凡的处理建筑应用程序,计算聚合过流或加入流在一起。
该设施有助于解决难题这种类型的应用面的:在处理乱序的数据,再处理输入作为代码的变化,执行有状态的计算等
API建立在芯中的基元流提供kafka:它使用用于输入的生产者和消费者的API,使用kafka有状态存储,并使用流处理器实例之间容错同一组的机制。

参考文章:
官文:Introduction to Kafka
分布式消息系统Kafka
Kafka背景及架构介绍