1、Kafka简介
Kafka是分布式发布-订阅消息系统,它最初由 LinkedIn 公司开发,使用 Scala语言编写,之后成为 Apache 项目的一部分。在Kafka集群中,没有“中心主节点”的概念,集群中所有的服务器都是对等的,因此,可以在不做任何配置的更改的情况下实现服务器的的添加与删除,同样的消息的生产者和消费者也能够做到随意重启和机器的上下线。
Kafka消息系统生产者和消费者部署关系图1-2
Kafka消息系统架构图1-3
Apache Kafka 是 一个分布式流处理平台。
流处理平台有以下三种特性:
1、可以让你发布和订阅流式的记录。这一方面与消息队列或者企业消息系统类似。
2、可以储存流式的记录,并且有较好的容错性。
3、可以在流式记录产生时就进行处理。
什么是kafka的优势?它主要应用于2大类应用:
1、构建实时的流数据管道,可靠地获取系统和应用程序之间的数据。
2、构建实时流的应用程序,对数据流进行转换或反应。
2、Kafka相关术语介绍
1、Producer:消息生产者,就是向Kafka broker发消息的客户端。
2、Consumer:消息消费者,向Kafka broker取消息的客户端。
3、Consumer Group(CG):消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
4、Broker:一台Kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。已发布的消息保存在一组服务器中,称之为Kafka集群。集群中的每一个服务器都是一个代理(Broker)。 消费者可以订阅一个或多个主题(topic),并从Broker拉数据,从而消费这些已发布的消息。
5、Topic:可以理解为一个队列,生产者和消费者面向的都是一个topic。Kafka将消息分门别类,每一类的消息称之为一个主题(Topic)。
6、Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。
7、Replication:副本。一个topic的每个分区都有若干个副本,一个Leader和若干个Follower。
8、Leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是Leader。
9、Follower:每个分区多个副本中的“从”,实时从Leader中同步数据,保持和Leader数据的同步。Leader发生故障时,某个Follower会成为新的Leader
Kafka的几个概念
-
kafka作为一个集群运行在一个或多个服务器上。
-
kafka集群存储的消息是以topic为类别记录的。
-
每个消息(也叫记录record,我习惯叫消息)是由一个key,一个value和时间戳构成。
Kafka的四个核心API
Producer API(生产者API)允许应用程序发布流记录到一个或多个kafka的主题。Consumer API(消费者API)允许应用程序订阅一个或多个主题和处理所产生的对他们的记录流。
Streams API(流API)允许应用程序作为流处理器,从一个消费输入流一个或多个主题,并产生一个输出流到一个或多个输出主题,高效地传输这个输入流到输出流。
Connector API(连接器API)允许构建和运行可重复使用的生产者或消费者连接kafka主题到现有的应用程序或数据系统。例如,关系数据库的连接器可能捕获对表的每个更改。
在Kafka中,客户端和服务器之间的通信是通过简单,高性能,语言无关的TCP协议完成的。此协议已版本化并保持与旧版本的向后兼容性。Kafka提供Java客户端,但客户端有多种语言版本。根据业务需求定制,而非实现一套类似ProtocolBuffer的通用协议。
Kafka的三大特点:
1、高吞吐量
可以满足每秒百万级别消息的生产和消费----生产消费。
2、持久性
有一套完善的消息存储机制,确保数据的高效安全的持久化---中间存储。
3、分布式
基于分布式的扩展和容错机制;kafka的数据都会复制到几台服务器上。当某一台故障失效时,生产者和消费者转而使用其他的机器----整体。
4、健壮性
Kafka的设计目标
1、高吞吐率 在廉价的商用机器上单机支持每秒100万条消息的读写
2、消息持久化 所有消息均被持久化到磁盘,无消息丢失,支持消息重放
3、完全分布式 Producer、Broker、Consumer均支持水平扩展
4、同时适应在线流处理和离线批处理
Topics主题和partitions分区
一个Topic可以认为是一类消息,每个topic将被分成多个partition(区),每个partition在存储层面是append log文件。Topic 是生产者发送消息的目标地址,是消费者的监听目标。
主题是发布记录的类别或订阅源名称。Kafka的主题总是多用户; 也就是说,一个主题可以有零个,一个或多个消费者订阅写入它的数据。
一个服务可以监听、发送多个 Topics。
Kafka 中有一个【consumer-group(消费者组)】的概念。
这是一组服务,扮演一个消费者。
如果是消费者组接收消息,Kafka 会把一条消息路由到组中的某一个服务。
这样有助于消息的负载均衡,也方便扩展消费者。
对于每个主题,Kafka群集都维护一个如下所示的分区日志:
每个分区都是一个有序的,不可变的记录序列,不断附加到结构化的提交日志中。分区中的记录每个都分配了一个称为偏移的顺序ID号,它唯一地标识分区中的每个记录。
Kafka集群持久保存所有已发布的记录 - 无论是否已使用 - 使用可配置的保留期。例如,如果保留策略设置为两天,则在发布记录后的两天内,它可供使用,之后将被丢弃以释放空间。Kafka的性能在数据大小方面实际上是恒定的,因此长时间存储数据不是问题。
实际上,基于每个消费者保留的唯一元数据是该消费者在日志中的偏移或位置。这种偏移由消费者控制:通常消费者在读取记录时会线性地提高其偏移量,但事实上,由于该位置由消费者控制,因此它可以按照自己喜欢的任何顺序消费记录。例如,消费者可以重置为较旧的偏移量来重新处理过去的数据,或者跳到最近的记录并从“现在”开始消费。
这些功能组合意味着Kafka 消费者consumers 非常cheap - 他们可以来来往往对集群或其他消费者没有太大影响。例如,您可以使用我们的命令行工具“tail”任何主题的内容,而无需更改任何现有使用者所消耗的内容。
日志中的分区有多种用途。首先,它们允许日志扩展到超出适合单个服务器的大小。每个单独的分区必须适合托管它的服务器,但主题可能有许多分区,因此它可以处理任意数量的数据。其次,它们充当了并行性的单位 - 更多的是它。
Broker消息服务代理
消息服务代理,kafka集群中的一个kafka服务节点称为一个broker,主要存储消息数据。一台kafka服务器就是一个broker。
Distribution分配
一个Topic的多个partitions,被分布在kafka集群中的多个server上;每个server(kafka实例)负责partitions中消息的读写操作;此外kafka还可以配置partitions需要备份的个数(replicas),每个partition将会被备份到多台机器上,以提高可用性.
基于replicated方案,那么就意味着需要对多个备份进行调度;每个partition都有一个server为"leader";leader负责所有的读写操作,如果leader失效,那么将会有其他follower来接管(成为新的leader);follower只是单调的和leader跟进,同步消息即可..由此可见作为leader的server承载了全部的请求压力,因此从集群的整体考虑,有多少个partitions就意味着有多少个"leader",kafka会将"leader"均衡的分散在每个实例上,来确保整体的性能稳定。
Producers生产者
Producers 将数据发布到指定的topics 主题。同时Producer 也能决定将此消息归属于哪个partition;比如基于"round-robin"方式或者通过其他的一些算法等。
一个服务可以同时为生产者和消费者。
Message消息
消息,是通信的基本单位,每个消息都属于一个partition。
Consumers
本质上kafka只支持Topic.每个consumer属于一个consumer group;反过来说,每个group中可以有多个consumer.发送到Topic的消息,只会被订阅此Topic的每个group中的一个consumer消费。
如果所有使用者实例具有相同的使用者组,则记录将有效地在使用者实例上进行负载平衡。
如果所有消费者实例具有不同的消费者组,则每个记录将广播到所有消费者进程。
分析:两个服务器Kafka群集,托管四个分区(P0-P3),包含两个使用者组。消费者组A有两个消费者实例,B组有四个消费者实例。
在Kafka中实现消费consumption 的方式是通过在消费者实例上划分日志中的分区,以便每个实例在任何时间点都是分配的“公平份额”的独占消费者。维护组中成员资格的过程由Kafka协议动态处理。如果新实例加入该组,他们将从该组的其他成员接管一些分区; 如果实例死亡,其分区将分发给其余实例。
Kafka仅提供分区内记录的总订单,而不是主题中不同分区之间的记录。对于大多数应用程序而言,按分区排序与按键分区数据的能力相结合就足够了。但是,如果您需要对记录进行总订单,则可以使用仅包含一个分区的主题来实现,但这将意味着每个使用者组只有一个使用者进程。
Zookeeper
协调Kafka的正常运行。
Consumers kafka确保
发送到partitions中的消息将会按照它接收的顺序追加到日志中。也就是说,如果记录M1由与记录M2相同的生成者发送,并且首先发送M1,则M1将具有比M2更低的偏移并且在日志中更早出现。
消费者实例按照它们存储在日志中的顺序查看记录。对于消费者而言,它们消费消息的顺序和日志中消息顺序一致。
如果Topic的"replicationfactor"为N,那么允许N-1个kafka实例失效,我们将容忍最多N-1个服务器故障,而不会丢失任何提交到日志的记录。
kafka作为消息系统
(1)传统消息系统
消息传统上有两种模型:queuing排队 and publish-subscribe发布 - 订阅。在队列中,消费者池可以从服务器读取并且每个记录转到其中一个; 在发布 - 订阅中,记录被广播给所有消费者。这两种模型中的每一种都有优点和缺点。排队的优势在于它允许您在多个消费者实例上划分数据处理,从而可以扩展您的处理。不幸的是,一旦一个进程读取它已经消失的数据,队列就不是多用户。发布 - 订阅允许您将数据广播到多个进程,但由于每条消息都发送给每个订阅者,因此无法进行扩展处理。
卡夫卡的消费者群体概念概括了这两个概念。与队列一样,使用者组允许您将处理划分为一组进程(使用者组的成员)。与发布 - 订阅一样,Kafka允许您向多个消费者组广播消息。
(2)kafka 的优势
Kafka模型的优势在于每个主题都具有这些属性 - 它可以扩展处理并且也是多用户 - 不需要选择其中一个。
与传统的消息系统相比,Kafka具有更强的订购保证。
传统队列在服务器上按顺序保留记录,如果多个消费者从队列中消耗,则服务器按照存储顺序分发记录。但是,虽然服务器按顺序分发记录,但是记录是异步传递给消费者的,因此它们可能会在不同的消费者处出现故障。这实际上意味着在存在并行消耗的情况下丢失记录的顺序。消息传递系统通常通过具有“独占消费者”概念来解决这个问题,该概念只允许一个进程从队列中消耗,但当然这意味着处理中没有并行性。
kafka做得更好。通过在主题中具有并行性概念 - 分区 - ,Kafka能够在消费者流程池中提供订购保证和负载平衡。这是通过将主题中的分区分配给使用者组中的使用者来实现的,以便每个分区仅由该组中的一个使用者使用。通过这样做,我们确保使用者是该分区的唯一读者并按顺序使用数据。由于有许多分区,这仍然可以平衡许多消费者实例的负载。但请注意,消费者组中的消费者实例不能超过分区。