0°

分布式消息中间件Kafka

Kafka介绍

是一种分布式,分区,复制的提交日志服务。它提供了消息传递系统的功能,但具有独特的设计。

首先让我们回顾一些基本的消息传递术语:

  • Kafka在称为主题的类别中维护消息的提要
  • 我们将消息发布到Kafka主题生成器的进程称为生产者。
  • 我们将订阅主题的进程并处理已发布消息的进程称为消费者。
  • Kafka作为由一个或多个服务器组成的集群运行,每个服务器称为Broker(代理)。

因此,在高层次上,生产者通过网络向Kafka集群发送消息,而Kafka集群又向消费者提供这样的服务:

分布式消息中间件Kafka

流媒体平台有三个关键功能:

  • 发布和订阅记录流,类似于消息队列或企业消息传递系统。
  • 以容错的持久方式存储记录流。
  • 记录发生时处理流。

Kafka通常用于两大类应用:

  • 构建可靠地在系统或应用程序之间获取数据的实时流数据管道
  • 构建转换或响应数据流的实时流应用程序

要了解Kafka如何做这些事情,让我们深入探讨Kafka的能力。

首先是几个概念:

  • Kafka作为一个集群运行在一个或多个可跨多个数据中心的服务器上。
  • Kafka集群以称为主题的类别存储记录流。
  • 每条记录由一个键,一个值和一个时间戳组成。

在Kafka中,客户端和服务器之间的通信是通过简单,高性能,语言无关的TCP协议完成的。此协议已版本化并保持与旧版本的向后兼容性。官方为Kafka提供Java客户端,但客户端有多种语言版本。

Topics and Logs(主题和日志(记录,数据))

让我们首先深入了解Kafka提供的高级抽象 - topic。 topic 是发布消息的类别或订阅源名称。对于每个topic,Kafka群集都维护一个分区日志,如下所示:

分布式消息中间件Kafka

每个分区都是一个有序的,不可变的消息序列,不断追加到提交日志中。分区中的消息每个都被分配一个称为偏移的顺序ID号,该ID唯一地标识分区中的每个消息。

Kafka群集保留所有已发布的消息 - 无论它们是否已被消费 - 在可配置的时间段内(默认为7天)。例如,如果将日志保留设置为两天,那么在发布消息后的两天内,它可供消费,之后将被丢弃以释放空间。 Kafka的性能在数据大小方面实际上是恒定的,因此保留大量数据不是问题。

事实上,基于每个消费者保留的唯一元数据是消费者在日志中的位置,称为“offset”(偏移量)。这种偏移量由消费者控制:消费者通常在读取消息时线性地提升其偏移量,但实际上该位置由消费者控制并且它可以按照其喜欢的任何顺序消费消息。例如,消费者可以重置为较旧的偏移量以进行重新处理。

这些功能组合意味着Kafka消费者消耗的成本非常低 - 他们可以来来往往对集群或其他消费者没有太大影响。例如,您可以使用我们的命令行工具“tail”任何主题的内容,而无需更改任何现有消费者所消耗的内容。

日志中的分区有多种用途。首先,它们允许日志扩展到超出适合单个服务器的大小。每个单独的分区必须适合托管它的服务器,但主题可能有许多分区,因此它可以处理任意数量的数据。其次,它们充当了并行性的单位 - 更多的是在一点上。

Distribution

日志的分区分布在Kafka集群中的服务器上,每个服务器处理数据并请求分区的共享。每个分区都在可配置数量的服务器上进行复制,以实现容错。

每个分区都有一个服务器充当“leader(领导者)”,零个或多个服务器充当“followers(追随者)”。leader(领导者)处理分区的所有读取和写入请求,而followers(追随者)被动地复制领导者。如果leader(领导者)失败,其中一个followers(追随者)将自动成为新的leader(领导者)。每个服务器都充当其某些分区的leader(领导者)和其他服务器的leader(领导者),因此负载在群集中很平衡。

这个领导者的选举由Zookeeper来完成。所有的Kafka服务器Broker(代理)先向Zookeeper注册上线,再由Zookeeper选举出处理分区的leader(领导者)与followers(追随者),leader(领导者)处理分区的所有读取和写入请求,而followers(追随者)被动地复制领导者。当数据写入Kafka时,先写入leader的分区,然后followers从zookeeper上找到leader,去leader服务器上复制数据,达成多副本的效果。当数据被消费时会从zookeeper上找到数据分区的leade及其followers,并行的去消费数据,因此负载在群集中很平衡。

Producers(生产者)

生产者将数据发布到他们选择的主题上。生产者负责选择将哪个消息分配给主题中的哪个分区。这可以通过循环方式完成,只是为了平衡负载,或者可以根据一些语义分区功能(例如基于消息中的某些键)来完成。更多关于在一秒钟内使用分区的信息。

Consumers

消息传统上有两种模型:队列和发布 - 订阅。在队列中,消费者池可以从服务器读取并且每个消息都到达其中一个消息;在发布 - 订阅中,消息被广播给所有消费者。 Kafka提供单一的消费者抽象,概括了这两者 - 消费者组。

消费者使用消费者组名称标记自己,并且发布到主题的每个消息都被传递到每个订阅消费者组中的一个消费者实例。消费者实例可以在单独的进程中,也可以在不同的机器

分布式消息中间件Kafka

如果所有使用者实例具有相同的使用者组,那么这就像传统的队列平衡对消费者的负载一样。 如果所有消费者实例具有不同的消费者组,则其工作方式类似于发布 - 订阅,并且所有消息都广播给所有消费者。

然而,更常见的是,我们发现主题具有少量的消费者组,每个都是“逻辑订阅者 ”。每个组由许多用于可伸缩性和容错的消费者实例组成。这只不过是发布 - 订阅语义,其中订阅者是消费者群集而不是单个进程。

与传统的消息系统相比,Kafka具有更强的订阅保证。

传统队列在服务器上按顺序保留消息,如果多个消费者从队列中消费,则服务器按照存储的顺序分发消息。但是,尽管服务器按顺序分发消息,但消息是异步传递给消费者的,因此它们可能会在不同的消费者上无序传送。这实际上意味着在并行消费的情况下消息的排序会丢失。消息传递系统通常通过具有“独占消费者”的概念来解决这个问题,该概念只允许一个进程从队列中消费,但当然这意味着处理中没有并行性。

Kafka做得更好。通过在主题中具有并行性概念 - 分区 - ,Kafka能够在消费者流程池中提供订阅保证和负载平衡。这是通过将主题中的分区分配给使用者组中的消费者来实现的,以便每个分区仅由该组中的一个消费者使用。通过这样做,我们确保消费者是该分区的唯一读者并按顺序使用数据。由于有许多分区,这仍然可以平衡许多消费者实例的负载。但请注意,除分区之外不能有更多的消费者实例。

Kafka仅对分区内的消息提供总订单,而不是在主题中的不同分区之间。对于大多数应用程序而言,按分区排序与按键分区数据的能力相结合就足够了。但是,如果您要请求消息的总订单,则可以使用仅包含一个分区的主题来实现此操作,但这仅表示一个消费者进程。

Guarantees(担保)

在高级别Kafka提供以下保证:

  • 生产者发送到特定主题分区的消息将按其发送顺序附加。也就是说,如果消息M1由与消息M2相同的生产者发送,并且首先发送M1,则M1将具有比M2更低的偏移并且在日志中更早出现。
  • 消费者实例按照它们存储在日志中的顺序查看消息。
  • 对于具有复制因子N的主题,我们将容忍最多N-1个服务器故障,而不会丢失任何提交给日志的消息。

有关这些保证的更多详细信息,请参见文档的设计部分。

Kafka查看版本

在Kafka的安装目录用命令查看版本

find ./libs/ -name \*_\* | head -1 | grep -o '\kafka[^\n]*'

Kafka查看topic

Kafka的元数据

 bin/kafka-topics.sh --list --zookeeper hdp:2181

Kafka创建新主题

Kafka创建新主题

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

Kafka使用

  • 使用生产者API时,往topic里面写消息时必须先在Kafka上新建好topic才由生产者往Kafka写消息
  • 消费者实例数*每个实例的消费线程数 <= topic的partition数量,否则多余的就浪费了
「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论