Apache Kafka 是一个分布式流处理平台,由 LinkedIn 开发并捐赠给 Apache 软件基金会,它主要用于构建实时数据流管道和流应用程序。Kafka 设计为高吞吐量、可扩展、容错和持久化,适用于处理大量数据。
Kafka 的核心特性包括:
-
高吞吐量:Kafka 能够处理高吞吐量的数据,每秒可以处理数十万条消息,这使得它非常适合大数据处理场景。
-
分布式架构:Kafka 由多个独立的服务器(称为 brokers)组成,这些服务器可以跨多个数据中心工作,提高了系统的可扩展性和容错性。
-
持久化存储:Kafka 将消息持久化到磁盘上,支持数据备份,确保数据不会因故障而丢失。
-
消息分区:Kafka 允许将主题(topics)划分为多个分区(partitions),每个分区可以由多个副本(replicas)复制,以提高并行性和可用性。
-
消息顺序性:在单个分区内,Kafka 保证了消息的顺序性,即消息将按照它们被发送的顺序进行处理。
-
可扩展性:Kafka 可以通过增加更多的 brokers 来轻松扩展,以处理更多的数据。
-
容错性:通过副本机制,Kafka 能够在节点故障的情况下继续提供服务,而不丢失消息。
-
高并发:Kafka 支持数千个客户端同时读写,适合高并发场景。
-
实时处理:Kafka 可以实时地处理数据流,支持实时分析和监控。
-
客户端库:Kafka 提供了多种编程语言的客户端库,包括 Java、Scala、Python 等,方便开发者使用。
-
生态系统集成:Kafka 与许多大数据生态系统工具集成,如 Hadoop、Spark、Flink 等,便于构建复杂的数据处理流程。
-
社区支持:作为 Apache 顶级项目,Kafka 拥有活跃的社区支持,不断有新特性和改进被加入。
Kafka 的这些特性使其成为处理实时数据流的理想选择,无论是用于日志聚合、事件源、实时分析还是构建复杂的流处理应用程序。
关键术语:
(1)生产者和消费者(producer和consumer):消息的发送者叫Producer,消息的使用者和接受者是Consumer,生产者将数据保存到Kafka集群中,消费者从中获取消息进行业务的处理。
(2)broker:Kafka集群中有很多台Server,其中每一台Server都可以存储消息,将每一台Server称为一个kafka实例,也叫做broker。
(3)主题(topic):一个topic里保存的是同一类消息,相当于对消息的分类,每个producer将消息发送到kafka中,都需要指明要存的topic是哪个,也就是指明这个消息属于哪一类。
(4)分区(partition):每个topic都可以分成多个partition,每个partition在存储层面是append log文件。任何发布到此partition的消息都会被直接追加到log文件的尾部。为什么要进行分区呢?核心是提升并发和分区扩展能力,单台服务器或者磁盘的性能受限制,可以同时多个分区写入或者读取,提供并发和水平扩展的能力。
(5)偏移量(Offset):一个分区对应一个磁盘上的文件,而消息在文件中的位置就称为offset(偏移量),offset为一个long型数字,它可以唯一标记一条消息。由于kafka并没有提供其他额外的索引机制来存储offset,文件只能顺序的读写,所以在kafka中几乎不允许对消息进行“随机读写”。
综上,我们总结一下Kafka的几个要点:
- kafka是一个基于发布-订阅的分布式消息系统(消息队列)
- Kafka面向大数据,消息保存在主题中,而每个topic有分为多个分区
- kafak的消息数据保存在磁盘,每个partition对应磁盘上的一个文件,消息写入就是简单的文件追加,文件可以在集群内复制备份以防丢失
- 即使消息被消费,kafka也不会立即删除该消息,可以通过配置使得过一段时间后自动删除以释放磁盘空间
- kafka依赖分布式协调服务Zookeeper,适合离线/在线信息的消费,与storm和saprk等实时流式数据分析常常结合使用
(三)Apache Kafka基本原理
通过之前的介绍,我们对kafka有了一个简单的理解,它的设计初衷是建立一个统一的信息收集平台,使其可以做到对信息的实时反馈。Kafka is a distributed,partitioned,replicated commit logservice。接下来我们着重从几个方面分析其基本原理。
1、分布式和分区(distributed、partitioned)
我们说kafka是一个分布式消息系统,所谓的分布式,实际上我们已经大致了解。消息保存在Topic中,而为了能够实现大数据的存储,一个topic划分为多个分区,每个分区对应一个文件,可以分别存储到不同的机器上,以实现分布式的集群存储。另外,每个partition可以有一定的副本,备份到多台机器上,以提高可用性。
总结起来就是:一个topic对应的多个partition分散存储到集群中的多个broker上,存储方式是一个partition对应一个文件,每个broker负责存储在自己机器上的partition中的消息读写。
2、副本(replicated )
kafka还可以配置partitions需要备份的个数(replicas),每个partition将会被备份到多台机器上,以提高可用性,备份的数量可以通过配置文件指定。
这种冗余备份的方式在分布式系统中是很常见的,那么既然有副本,就涉及到对同一个文件的多个备份如何进行管理和调度。kafka采取的方案是:每个partition选举一个server作为“leader”,由leader负责所有对该分区的读写,其他server作为follower只需要简单的与leader同步,保持跟进即可。如果原来的leader失效,会重新选举由其他的follower来成为新的leader。
至于如何选取leader,实际上如果我们了解ZooKeeper,就会发现其实这正是Zookeeper所擅长的,Kafka 使用 ZK 在 Broker 中选出一个 Controller,用于 Partition 分配和 Leader 选举。
另外,这里我们可以看到,实际上作为leader的server承担了该分区所有的读写请求,因此其压力是比较大的,从整体考虑,从多少个partition就意味着会有多少个leader,kafka会将leader分散到不同的broker上,确保整体的负载均衡。
3、整体数据流程
Kafka 的总体数据流满足下图,该图可以说是概括了整个kafka的基本原理。
(1)数据生产过程(Produce)
对于生产者要写入的一条记录,可以指定四个参数:分别是topic、partition、key和value,其中topic和value(要写入的数据)是必须要指定的,而key和partition是可选的。
对于一条记录,先对其进行序列化,然后按照 Topic 和 Partition,放进对应的发送队列中。如果 Partition 没填,那么情况会是这样的:a、Key 有填。按照 Key 进行哈希,相同 Key 去一个 Partition。b、Key 没填。Round-Robin 来选 Partition。
producer将会和Topic下所有partition leader保持socket连接,消息由producer直接通过socket发送到broker。其中partition leader的位置(host:port)注册在zookeeper中,producer作为zookeeper client,已经注册了watch用来监听partition leader的变更事件,因此,可以准确的知道谁是当前的leader。
producer端采用异步发送:将多条消息暂且在客户端buffer起来,并将他们批量的发送到broker,小数据IO太多,会拖慢整体的网络延迟,批量延迟发送事实上提升了网络效率。
(2)数据消费过程(Consume)
对于消费者,不是以单独的形式存在的,每一个消费者属于一个consumer group,一个group包含多个consumer。特别需要注意的是:订阅Topic是以一个消费组来订阅的,发送到Topic的消息,只会被订阅此Topic的每个group中的一个consumer消费。
如果所有的Consumer都具有相同的group,那么就像是一个点对点的消息系统;如果每个consumer都具有不同的group,那么消息会广播给所有的消费者。
具体说来,这实际上市根据partition来分的,一个 Partition,只能被消费组里的一个消费者消费,但是可以同时被多个消费组消费,消费组里的每个消费者是关联到一个partition的,因此有这样的说法:对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。
同一个消费组的两个消费者不会同时消费一个partition。
在kafka中,采用了pull方式,即consumer在和broker建立连接之后,主动去pull(或者说fetch)消息,首先consumer端可以根据自己的消费能力适时的去fetch消息并处理,且可以控制消息消费的进度(offset)。
partition中的消息只有一个consumer在消费,且不存在消息状态的控制,也没有复杂的消息确认机制,可见kafka broker端是相当轻量级的。当消息被consumer接收之后,需要保存 Offset 记录消费到哪,以前保存在 ZK 中,由于 ZK 的写性能不好,以前的解决方法都是 Consumer 每隔一分钟上报一次,在 0.10 版本后,Kafka 把这个 Offset 的保存,从 ZK 中剥离,保存在一个名叫 consumeroffsets topic 的 Topic 中,由此可见,consumer客户端也很轻量级。
4、消息传送机制
Kafka 支持 3 种消息投递语义,在业务中,常常都是使用 At least once 的模型。
- At most once:最多一次,消息可能会丢失,但不会重复。
- At least once:最少一次,消息不会丢失,可能会重复。
- Exactly once:只且一次,消息不丢失不重复,只且消费一次。
参考链接:
注:本文是一个总结性笔记,参考了一些其他写的不错的文章,特在此进行说明,主要如下:
https://www.cnblogs.com/gzshan/p/10957920.html