kafka

1.1       kafka(分布式发布订阅消息系统)

1.1.1     产品介绍

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

发布和订阅记录流,类似于消息队列或企业消息系统。

以容错的持久方式存储记录流。

在记录发生时处理记录流。

Kafka通常用于两大类应用程序:

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

构建实时流应用程序,转换或响应数据流

首先是一些概念:

Kafka作为集群运行在一个或多个服务器上,这些服务器可以跨多个数据中心。

Kafka集群将记录流存储在称为主题的类别中。每条记录由一个键、一个值和一个时间戳组成。

1.1.1.1               Kafka有四个核心api:

Producer API允许应用程序将记录流发布到一个或多个Kafka主题。

消费者API允许应用程序订阅一个或多个主题,并处理向它们生成的记录流。

Streams API允许应用程序充当流处理器,使用来自一个或多个主题的输入流,并将输出流生成到一个或多个输出主题,从而有效地将输入流转换为输出流。

连接器API允许构建和运行可重用的生产者或消费者,这些生产者或消费者将Kafka主题连接到现有的应用程序或数据系统。例如,到关系数据库的连接器可能会捕获对表的每次更改。

 

在Kafka中,客户端和服务器之间的通信使用简单、高性能、语言无关的TCP协议完成。该协议经过版本控制,并与旧版本保持向后兼容性。我们为Kafka提供了一个Java客户端,但是客户端可以使用多种语言。

1.1.1.2               主题和日志

让我们首先深入了解Kafka为记录流(主题)提供的核心抽象。

主题是发布记录的类别或提要名称。卡夫卡中的主题始终是多订阅者的;也就是说,一个主题可以有零个、一个或多个订阅其所写数据的消费者。

对于每个主题,Kafka集群维护一个分区日志,如下所示:

 

每个分区都是一个有序的、不可变的记录序列,这些记录连续地附加到一个结构化的提交日志中。分区中的每条记录都被分配了一个名为偏移量的连续id号,该偏移量惟一地标识分区中的每条记录。

Kafka集群使用一个可配置的保留期持久地保存所有已发布的记录(无论它们是否已被使用)。例如,如果保留策略被设置为两天,那么在记录发布后的两天内,它是可用的,在此之后,它将被丢弃以释放空间。Kafka的性能在数据大小方面是稳定的,所以长时间存储数据不是问题。

 

实际上,在每个使用者的基础上保留的惟一元数据是该使用者在日志中的偏移量或位置。这个偏移量由使用者控制:通常,使用者在读取记录时将线性地推进它的偏移量,但是,实际上,由于位置由使用者控制,所以它可以按照自己喜欢的任何顺序使用记录。例如,使用者可以重置为较早的偏移量,以便重新处理来自过去的数据,或者跳过到最近的记录,从“现在”开始消费。

这些特性的组合意味着Kafka消费者非常便宜——他们可以来来去去,而不会对集群或其他消费者造成太大影响。例如,您可以使用我们的命令行工具“跟踪”任何主题的内容,而不需要更改任何现有使用者所使用的内容。

日志中的分区有几个用途。首先,它们允许日志扩展到超出单个服务器所能容纳的大小。每个单独的分区必须适合承载它的服务器,但是一个主题可能有多个分区,因此它可以处理任意数量的数据。其次,它们作为平行度的单位——在这一点上还有一点。

1.1.1.3               分布

日志的分区分布在Kafka集群中的服务器上,每个服务器处理数据并请求共享分区。为了容错,每个分区被复制到多个可配置的服务器上。

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

1.1.1.4               Geo-Replication

Kafka MirrorMaker为集群提供地理复制支持。使用MirrorMaker,消息可以跨多个数据中心或云区域复制。您可以在用于备份和恢复的主动/被动场景中使用它;或在活动/活动场景中,将数据放置到离用户更近的位置,或支持数据本地化需求。

1.1.1.5               生产者

生产者将数据发布到他们选择的主题。生产者负责选择要分配给主题中的哪个分区的记录。这可以通过循环方式来完成,只是为了平衡负载,也可以根据语义分区函数(比如基于记录中的某个键)来完成。稍后将详细介绍分区的使用!

1.1.1.6               消费者

使用者使用使用者组名称给自己贴标签,每个发布到主题的记录被交付到每个订阅使用者组中的一个使用者实例。使用者实例可以位于单独的进程中,也可以位于单独的机器上。

如果所有使用者实例都具有相同的使用者组,那么记录将有效地在使用者实例上进行负载平衡。

如果所有使用者实例具有不同的使用者组,则每个记录将广播到所有使用者进程。

 

一个包含四个分区(P0-P3)的两台服务器Kafka集群,包含两个用户组。消费者组A有两个消费者实例,而B组有四个。

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

Kafka中实现消费的方法是在使用者实例上划分日志中的分区,这样每个实例在任何时候都是分区“公平共享”的独占使用者。这个维护组成员关系的过程由Kafka协议动态处理。如果新实例加入组,它们将从组的其他成员那里接管一些分区;如果一个实例死亡,它的分区将分配给其余的实例。

Kafka只提供分区内记录的总顺序,而不是主题中不同分区之间的顺序。对大多数应用程序来说,按分区排序和按键分区数据的能力已经足够了。但是,如果您需要记录的总顺序,则可以使用只有一个分区的主题来实现这一点,尽管这意味着每个使用者组只有一个使用者进程。

1.1.1.7               多租户

您可以将Kafka部署为一个多租户解决方案。通过配置哪些主题可以生成或使用数据,可以启用多租户。还有对配额的操作支持。管理员可以对请求定义和强制配额,以控制客户端使用的代理资源。有关更多信息,请参见安全性文档。

1.1.1.8               担保

卡夫卡在高层给出了以下保证:

生产者发送到特定主题分区的消息将按发送顺序追加。也就是说,如果记录M1是由与记录M2相同的生产者发送的,并且M1是先发送的,那么M1的偏移量将比M2低,并且出现在日志的前面。

使用者实例按记录存储在日志中的顺序查看记录。

对于具有复制因子N的主题,我们将容忍最多N-1个服务器故障,而不会丢失提交到日志的任何记录。

有关这些保证的更多细节将在文档的设计部分中给出。

1.1.1.9               Kafka作为一个消息系统

Kafka的流概念与传统的企业消息系统相比如何?

消息传递传统上有两种模型:排队和发布-订阅。在队列中,一个消费者池可以从一个服务器读取数据,并且每个记录将被发送到其中一个;在publish-subscribe中,记录被广播给所有消费者。这两种模式各有优缺点。排队的优势在于,它允许您在多个使用者实例上划分数据处理,从而允许您扩展处理。不幸的是,队列不是多订阅者的—一旦一个进程读取了它丢失的数据。发布-订阅允许您将数据广播到多个进程,但是由于每个消息都发送到每个订阅者,因此无法扩展处理。

Kafka中的消费者群体概念概括了这两个概念。与队列一样,使用者组允许您将处理划分到一组进程(使用者组的成员)上。与发布-订阅一样,Kafka允许您向多个消费者组广播消息。

卡夫卡模型的优势在于,每个主题都具有这两种属性——可以扩展处理,而且是多订阅者的——不需要选择其中之一。

Kafka也比传统的消息传递系统有更强的订购保证。

传统队列在服务器上按顺序保留记录,如果多个消费者从队列中消费,则服务器按存储记录的顺序分发记录。然而,尽管服务器按顺序分发记录,但是这些记录是异步传递给使用者的,因此它们可能在不同的使用者上出现顺序错误。这实际上意味着记录的顺序在并行使用时丢失。消息传递系统通常通过“独占消费者”的概念来解决这个问题,该概念只允许一个进程从队列中消费,但这当然意味着处理中不存在并行性。

卡夫卡做得更好。通过在主题中具有并行性(分区)的概念,Kafka能够在用户进程池上提供排序保证和负载平衡。这是通过将主题中的分区分配给使用者组中的使用者来实现的,以便每个分区恰好由组中的一个使用者使用。通过这样做,我们确保使用者是该分区的唯一读取者,并按顺序使用数据。由于有许多分区,这仍然可以在许多使用者实例上平衡负载。但是请注意,在一个使用者组中不能有多于分区的使用者实例。

1.1.1.10      Kafka as a Storage System

写入Kafka的数据被写入磁盘并复制,以获得容错能力。Kafka允许生产者等待确认,这样直到完全复制并确保即使写入的服务器失败,写入也不会被认为是完整的。

Kafka使用的磁盘结构伸缩性很好,无论服务器上有50 KB还是50 TB的持久数据,Kafka都会执行相同的操作。

由于认真对待存储并允许客户端控制其读取位置,您可以将Kafka看作一种专用于高性能、低延迟提交日志存储、复制和传播的分布式文件系统。

1.1.1.11      Kafka for Stream Processing

仅仅读取、写入和存储数据流是不够的,其目的是实现流的实时处理。

在Kafka中,流处理器是指从输入主题获取连续的数据流,对这个输入执行一些处理,并产生连续的数据流到输出主题。

例如,一个零售应用程序可能接受销售和发货的输入流,并根据这些数据计算出重新订购和价格调整的输出流。

可以直接使用生产者和消费者api进行简单的处理。但是对于更复杂的转换,Kafka提供了一个完全集成的Streams API。这允许构建进行非平凡处理的应用程序,这些处理可以计算流之外的聚合或将流连接在一起。

此功能有助于解决此类应用程序所面临的难题:处理无序数据、在代码更改时重新处理输入、执行有状态计算等等。

streams API构建在Kafka提供的核心原语之上:它使用生产者和消费者API进行输入,使用Kafka进行有状态存储,并使用相同的组机制在流处理器实例之间进行容错。

1.1.1.12      Putting the Pieces Together

通过结合存储和低延迟订阅,流应用程序可以以相同的方式处理过去和未来的数据。也就是说,一个应用程序可以处理历史上存储的数据,但是当它到达最后一条记录时,它可以在未来的数据到达时继续处理,而不是结束。这是流处理的一个广义概念,包括批处理和消息驱动应用程序。

同样,对于流数据管道,订阅实时事件的组合使使用Kafka处理非常低延迟的管道成为可能;但是,可靠地存储数据的能力使其能够用于必须保证数据交付的关键数据,或者用于与离线系统集成,离线系统只定期加载数据,或者可能在很长一段时间内停机以进行维护。流处理设施使得在数据到达时转换数据成为可能。

1.1.2     指标

Kafka通常用于操作监控数据。这包括聚合来自分布式应用程序的统计信息,以生成操作数据的集中提要。

1.1.2.1               日志聚合

许多人使用Kafka作为日志聚合解决方案的替代品。日志聚合通常从服务器收集物理日志文件,并将它们放在中心位置(可能是文件服务器或HDFS)进行处理。Kafka抽象了文件的细节,并将日志或事件数据作为消息流提供了更清晰的抽象。这允许较低的延迟处理,更容易支持多个数据源和分布式数据消费。与Scribe或Flume等以日志为中心的系统相比,Kafka提供了同样好的性能、由于复制而提供的更强的持久性保证以及更低的端到端延迟。

1.1.2.2               流处理

Kafka的许多用户在由多个阶段组成的处理管道中处理数据,从Kafka主题使用原始输入数据,然后聚合、丰富或以其他方式转换为新的主题,以便进一步使用或后续处理。例如,用于推荐新闻文章的处理管道可以从RSS提要中抓取文章内容并将其发布到“文章”主题;进一步处理可将此内容规范化或删除,并将已清理的文章内容发布到新主题;最后一个处理阶段可能尝试向用户推荐这些内容。这样的处理管道根据各个主题创建实时数据流图。从0.10.0.0开始,Apache Kafka中提供了一个轻量级但功能强大的流处理库Kafka,用于执行上述数据处理。除了Kafka流之外,其他开源流处理工具还包括Apache Storm和Apache Samza。

1.1.2.3               事件的采购

事件源是一种应用程序设计风格,其中状态更改记录为按时间顺序排列的记录序列。Kafka对非常大的存储日志数据的支持使其成为以这种风格构建的应用程序的优秀后端。

1.1.2.4               提交日志

Kafka可以作为分布式系统的一种外部提交日志。日志帮助在节点之间复制数据,并充当失败节点恢复数据的重新同步机制。Kafka中的日志压缩特性有助于支持这种用法。在这种用法中,Kafka类似于Apache BookKeeper项目。

1.1.3     环境搭建

1.1.3.1               下载

http://kafka.apache.org/downloads

 

1.1.3.2               安装kafka

Kafka依赖于zookeeper集群,JDK,zk的安装此处不再讲述

  1. 1.  在用户有完全文件权限的路径下执行tar -xzf kafka_2.12-2.2.0.tgz
  2. 设置环境变量:

export KAFKA_HOME=

export PATH=$PATH: KAFKA_HOME/bin

  1. 3.  文件配置:

[kafka/config/server.properties]

       ...

       broker.id=服务器编号

       ...

       listeners=PLAINTEXT://:9092 

       ...

       log.dirs=/home/centos/kafka/logs –日志路径

       ...

    zookeeper.connect=ip:port  --以,分割多个服务器

  1. 4.  分发各安装卡夫卡的服务器
  2. 5.  启动:先启动zk,再启动kafka:bin/kafka-server-start.sh config/server.properties

1.1.3.3          Create a topic

创建topic主题

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

查看运行topic主题

bin/kafka-topic.sh –list zookeeper ip:2181

posted @ 2019-08-14 11:25  星辰大海-sdifens  阅读(222)  评论(0编辑  收藏  举报