一、kafka简介
Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java语言编写。Kafka是一种高吞吐量的分布式发布-订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。kafka是用于构建实时数据管道和流应用程序。具有横向扩展、容错、快速等优点,并已在成千上万家公司运行。和redis、rabbitmq等消息中间件一样,Apache kafka也是消息中间件的一种,只是每个消息中间件的定位不太相同,适用场景也不太一致。
Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica)、基于zookeeper协调的分布式消息系统,它最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎、web/nginx日志、访问日志、消息服务等。Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
主要应用场景如下:
(1)消息系统
Kafka可以作为传统消息系统的替代。相比传统消息系统,Kafka有更高的吞吐量、拥有内置的分区Partition、复制备份高容错能力。传统消息系统对高吞吐量没有过高要求,但kafka的低延迟特性和强大的备份容错能力是传统消息所必须的。
(2)网站行为追踪
Kafka可用于用户行为追踪,通过将用户行为数据发送给Kafka,以此为基础,实现用户行为在线与离线分析,可用于网站实时监控与异常行为拦截等。
(3)日志收集
Kafka可以作为日志收集解决方案。日志收集通常是将不同服务器的日志文件收集到一个中心区域,Kafka实现了对日志文件数据进行抽象,统一了处理接口。Kafka低延迟,支持不同的日志数据源,分布式消费易于扩展,可同时将数据提供给hdfs、storm、监控软件等等。
(4)应用监控
Kafka可用于监控运行中的应用系统。如收集分布式应用的数据进行聚合计算,进行分析检测异常情况。
需要注意以下三点:
- kafka作为一个集群运行在一个或多个服务器上;
- kafka集群存储的消息是以topic为类别记录的;
- 每个消息(也叫记录record)是由一个key,一个value和时间戳构成。
二、kafka特性
Kafka是一种高吞吐量的分布式发布订阅消息系统,它专为分布式高吞吐量系统而设计。与其他消息传递系统相比,Kafka具有更好的吞吐量,内置分区,复制和固有的容错能力,这使得它非常适合大规模消息处理应用程序。
具有如下特性:
(1)以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证多数时间的访问性能。
(2)高吞吐量:即使在非常廉价的商用机器上也能做到单机支持每秒百万条消息的传输。
(3)支持Kafka Server间的消息分区及分布式消费,同时保证每个partition(分区)内的消息顺序传输。
(4)同时支持离线数据处理和实时数据处理。
(5)支持Hadoop并行数据加载。
(6)Scale out:支持在线水平扩展。
Kafka将消息保留在磁盘上,并在群集内复制以防止数据丢失。 Kafka构建在ZooKeeper同步服务之上。它与Apache Storm和Spark非常好地集成,用于实时流式数据分析。
三、术语介绍
一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:点对点传递模式、发布-订阅模式。大部分的消息系统选用发布-订阅模式。Kafka就是一种发布-订阅模式。
(1)点对点消息传递模式
在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。这种架构描述示意图如下:
(2)发布-订阅消息传递模式
在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,但数据被消费后不会立马删除,数据保留是期限的,默认是7天,因为他不是存储系统。
kafka有两种方式,一种是是消费者去主动去消费(拉取)消息,而不是生产者推送消息给消费者;另外一种就是生产者主动推送消息给消费者,类似公众号。
在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。该模式的示例图如下:
kafka中最重要的几个关键术语及其关系如下图所示:
上图中一个topic配置了3个partition。Partition1有两个offset:0和1。Partition2有4个offset。Partition3有1个offset。副本的id和副本所在的机器的id恰好相同。如果一个topic的副本数为3,那么Kafka将在集群中为每个partition创建3个相同的副本。集群中的每个broker存储一个或多个partition。多个producer和consumer可同时生产和消费数据。
(1)术语之broker
Kafka集群包含一个或多个服务器,这种服务器被称为broker。broker存储topic的数据。
如果某topic有N个partition,集群有N个broker,那么每个broker存储该topic的一个partition。
如果某topic有N个partition,集群有(N+M)个broker,那么其中有N个broker存储该topic的一个partition,剩下的M个broker不存储该topic的partition数据。
如果某topic有N个partition,集群中broker数目少于N个,那么一个broker存储该topic的一个或多个partition。在实际生产环境中,尽量避免这种情况的发生,这种情况容易导致Kafka集群数据不均衡。
(2)术语之Topic
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处),Topic即主题,通过对消息指定主题可以将消息分类,消费者可以只关注自己需要的Topic中的消息。
属于特定类别的消息流称为主题。数据存储在主题中,Topic相当于Queue。主题被拆分成分区,每个这样的分区包含不可变有序序列的消息,分区被实现为具有相等大小的一组分段文件。
(3)术语之Partition
Partition(分区)是物理上的概念,每个Topic包含一个或多个Partition。每个topic至少有一个partition。每个partition中的数据使用多个segment文件存储。任何发布到此Partition的消息都会被追加到Log文件的尾部,在分区中的每条消息都会按照时间顺序分配到一个单调递增的顺序编号,也就是我们的Offset,Offset是一个Long型的数字。我们通过这个Offset可以确定一条在该Partition下的唯一消息,在Partition下面是保证了有序性,但是在Topic下面没有保证有序性。如下图所示:
- 一个Topic可以分成多个Partition,这是为了平行化处理;
- 每个Partition内部消息有序,其中每个消息都有一个offset序号;
- 一个Partition只对应一个Broker,一个Broker可以管理多个Partition。
Partition offset(分区偏移):每个分区消息具有称为offset的唯一序列标识。
Replicas of partition(分区备份):副本只是一个分区的备份。 副本从不读取或写入数据。 它们主要用于防止数据丢失。
在每个分区中,消息以顺序存储,最晚接收的消息会最后被消费。
(4)术语之Producer
生产者即数据的发布者,该角色将消息发布到Kafka的topic中。broker接收到生产者发送的消息后,broker将该消息追加到当前用于追加数据的segment文件中。生产者在向kafka集群发送消息的时候,可以通过指定分区来发送到指定的分区中,也可以通过指定均衡策略来将消息发送到不同的分区中;如果不指定,就会采用默认的随机均衡策略,将消息随机的存储到不同的分区中。
(5)术语之Consumer
Consumer即消费者,消费者通过与kafka集群建立长连接的方式,不断地从集群中拉取消息,然后可以对这些消息进行处理。消费者可以消费多个topic中的数据。
(6)术语之Consumer Group
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
在消费者消费消息时,kafka使用offset来记录当前消费的位置。在kafka的设计中,可以有多个不同的group同时消费同一个topic下的消息,如下图所示,
我们有两个不同的group同时消费同一个topic中的消息,他们消费的记录位置offset各不项目,不互相干扰。
对于一个group而言,消费者的数量不应该多余分区的数量,因为在一个group中,每个分区至多只能绑定到一个消费者上,即一个消费者可以消费多个分区,一个分区只能给一个消费者消费。因此,若一个group中的消费者数量大于分区数量的话,多余的消费者将不会收到任何消息。
(7)术语之Leader
每个partition有多个副本,其中有且仅有一个作为Leader,Leader是当前负责数据的读写的partition。
(8)术语之Follower
Follower跟随Leader,所有写请求都通过Leader路由,数据变更会广播给所有Follower,Follower与Leader保持数据同步。如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个follower。
参考博文:
(1)https://blog.csdn.net/u012129558/article/details/80065869
(2)https://www.cnblogs.com/qingyunzong/p/9004509.html (值得仔细阅读一下)
(3)https://baike.baidu.com/item/Kafka/17930165?fr=aladdin
(4)https://zhuanlan.zhihu.com/p/58658870
(5)https://www.orchome.com/5
(6)https://developer.51cto.com/art/201808/581538.htm