一、kafka简介
Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java语言编写。Kafka是一种高吞吐量的分布式发布-订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。
Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。kafka是用于构建实时数据管道和流应用程序。具有横向扩展、容错、快速等优点,并已在成千上万家公司运行。和redis、rabbitmq等消息中间件一样,Apache kafka也是消息中间件的一种,只是每个消息中间件的定位不太相同,适用场景也不太一致。
Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/Nginx日志、访问日志,消息服务等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
主要应用场景是:日志收集系统和消息系统。
二、kafka特性
Kafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:
(1)以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证多数时间的访问性能。
(2)高吞吐量:即使在非常廉价的商用机器上也能做到单机支持每秒百万条消息的传输。
(3)支持Kafka Server间的消息分区及分布式消费,同时保证每个partition(分区)内的消息顺序传输。
(4)同时支持离线数据处理和实时数据处理。
(5)支持Hadoop并行数据加载。
(6)Scale out:支持在线水平扩展。
三、术语介绍
一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:点对点传递模式、发布-订阅模式。大部分的消息系统选用发布-订阅模式。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中的消息。
(3)术语之Partition
Partition(分区)是物理上的概念,每个Topic包含一个或多个Partition。每个topic至少有一个partition。每个partition中的数据使用多个segment文件存储。partition中的数据是有序的,不同partition间的数据丢失了数据的顺序。如果topic有多个partition,消费数据时就不能保证数据的顺序。因此,在需要严格保证消息的消费顺序的场景下,需要将partition数目设为1。
在每个分区中,消息以顺序存储,最晚接收的消息会最后被消费。
(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