Kafka名字的由来:
Kafka 作者之一 Jay Kreps 曾经谈及过命名的原因。因为 Kafka 系统的写性能很强,所以找了个作家的名字来命名似乎是一个好主意。大学期间我上了很多文学课,非常喜欢 Franz Kafka 这个作家,另外为开源软件起这个名字听上去很酷。
消息引擎
消息设计出来之后还不够,消息引擎系统还要设定具体的传输协议,即我用什么方法把消息传输出去。常见的有两种方法:
- 点对点模型:也叫消息队列模型。日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。
- 发布 / 订阅模型:与上面不同的是,它有一个主题(Topic)的概念,你可以理解成逻辑语义相近的消息容器。该模型也有发送方和接收方,只不过提法不同。发送方也称为发布者(Publisher),接收方称为订阅者(Subscriber)。和点对点模型不同的是,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布 / 订阅模型。
- Apache Kafka是一款开源的消息引擎系统。根据维基百科的定义,消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。通俗来讲,
就是系统A发送消息给消息引擎系统,系统B从消息引擎系统中读取A发送的消息
。 - 消息引擎系统要设定具体的传输协议,即我用什么方法把消息传输出去,常见的方法有2种:点对点模型和发布/订阅模型。Katka同时支持这两种消息引擎模型。
- 系统A不能直接发送消息给系统B,中间还要隔一个消息引擎呢,是为了“削峰填谷”。
为什么系统 A 不能直接发送消息给系统 B,中间还要隔一个消息引擎呢?
答案就是“削峰填谷”。所谓的“削峰填谷”就是指缓冲上下游瞬时突发流量,使其更平滑。特别是对于那种发送能力很强的上游系统,如果没有消息引擎的保护,“脆弱”的下游系统可能会直接被压垮导致全链路服务“雪崩”。但是,一旦有了消息引擎,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡。消息引擎系统的另一大好处在于发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。
Kafka术语
-
Topic
:Kafka 属于分布式的消息引擎系统,它的主要功能是提供一套完备的消息发布与订阅解决方案。在 Kafka 中,发布订阅的对象是主题(Topic),你可以为每个业务、每个应用甚至是每类数据都创建专属的主题 -
Producer
:向主题发布消息的客户端应用程序称为生产者(Producer),生产者程序通常持续不断地向一个或多个主题发送消息 -
Consumer
:订阅这些主题消息的客户端应用程序就被称为消费者(Consumer) -
Clients
:把生产者和消费者统称为客户端(Clients) -
服务器端
:Kafka 的服务器端由被称为 Broker 的服务进程构成,即一个 Kafka 集群由多个 Broker 组成,Broker 负责接收和处理客户端发送过来的请求,以及对消息进行持久化。虽然多个 Broker 进程能够运行在同一台机器上,但更常见的做法是将不同的 Broker 分散运行在不同的机器上,这样如果集群中某一台机器宕机,即使在它上面运行的所有 Broker 进程都挂掉了,其他机器上的 Broker 也依然能够对外提供服务。这其实就是 Kafka 提供高可用的手段之一。实现高可用的另一个手段就是备份机制(Replication)。备份的思想很简单,就是把相同的数据拷贝到多台机器上,而这些相同的数据拷贝在 Kafka 中被称为副本(Replica)。 -
Replica
:副本。Kafka 定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)。前者对外提供服务,这里的对外指的是与客户端程序进行交互;而后者只是被动地追随领导者副本而已,不能与外界进行交互。副本的工作机制:生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,它只做一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。
为什么 Kafka 不像 MySQL 那样允许追随者副本对外提供读服务?
首先明确一下:主从分离与否没有绝对的优劣,它仅仅是一种架构设计,各自有适用的场景。
第二、Redis和MySQL都支持主从读写分离,这和它们的使用场景有关。对于那种读操作很多而写操作相对不频繁的负载类型而言,采用读写分离是非常不错的方案—我们可以添加很多follower横向扩展,提升读操作性能。反观Kafka,它的主要场景还是在消息引擎而不是以数据存储的方式对外提供读服务,通常涉及频繁地生产消息和消费消息,这不属于典型的读多写少场景,因此读写分离方案在这个场景下并不太适合。
第三、Kafka副本机制使用的是异步消息拉取,因此存在leader和follower之间的不一致性。如果要采用读写分离,必然要处理副本延迟引入的一致性问题,比如如何实现read—your—writes,如何保证单调读(monotonic reads)以及处理消息因果顺序颠倒的问题。相反地,如果不采用读写分离,所客户端读写请求都只在Leader上处理也就没有这些问题了—当然最后全局消息顺序颠倒的问题在Kafka中依然存在,常见的解决办法是使用单分区,其他的方案还有version vector,但是目前Kafka没有提供。
最后、社区正在考虑引入适度的读写分离方案,比如允许某些指定的follower副本(主要是为了考虑地理相近性)可以对外提供读服务。当然目前这个方案还在讨论中。 -
Kakfa中的分区机制
:Kafka 中的分区机制指的是将每个主题划分成多个分区(Partition),每个分区是一组有序的消息日志。生产者生产的每条消息只会被发送到一个分区中,也就是说如果向一个双分区的主题发送一条消息,这条消息要么在分区 0 中,要么在分区 1 中。如你所见,Kafka 的分区编号是从 0 开始的,如果 Topic 有 100 个分区,那么它们的分区号就是从 0 到 99。一个主题可以划分为M个分区。
一个分区内可以有N个副本,其中一个是Leader副本,负责对外提供服务,其中N-1个是Follower副本,只是提供数据冗余的作用。
每个分区中包含若干条消息,每条消息的位移从0开始,依次递增。
-
Kafka 使用
消息日志(Log)
来保存数据,一个日志就是磁盘上一个只能追加写(Append-only)消息的物理文件。因为只能追加写入,故避免了缓慢的随机 I/O 操作,改为性能较好的顺序 I/O 写操作,这也是实现 Kafka 高吞吐量特性的一个重要手段。 -
(Log Segment)机制
:如果不停地向一个日志写入消息,最终也会耗尽所有的磁盘空间,因此 Kafka 必然要定期地删除消息以回收磁盘。怎么删除呢?简单来说就是通过日志段(Log Segment)机制。在 Kafka 底层,一个日志又进一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,Kafka 会自动切分出一个新的日志段,并将老的日志段封存起来。Kafka 在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的。 -
Consumer Group
:消费者组。Kafka提供两种消息模型,即点对点模型(Peer to Peer,P2P)和发布订阅模型。这里面的点对点指的是同一条消息只能被下游的一个消费者消费,其他消费者则不能染指。在 Kafka 中实现这种 P2P 模型的方法就是引入了消费者组(Consumer Group)。所谓的消费者组,指的是多个消费者实例共同组成一个组来消费一组主题。这组主题中的每个分区都只会被组内的一个消费者实例消费,其他消费者实例不能消费它。为什么要引入消费者组呢?主要是为了提升消费者端的吞吐量。多个消费者实例同时消费,加速整个消费端的吞吐量(TPS)。消费者组里面的所有消费者实例不仅“瓜分”订阅主题的数据,它们还能彼此协助。假设组内某个实例挂掉了,Kafka 能够自动检测到,然后把这个挂掉的实例之前负责的分区转移给其他活着的消费者。这个过程就是 Kafka 中的“重平衡”(Rebalance)。
Kafka是什么
Apache Kafka 是消息引擎系统,也是一个分布式流处理平台(Distributed Streaming Platform)
- Kafka在设计之初就旨在提供三个方面的特性:提供一套API实现生产者和消费者;降低网络传输和磁盘存储开销;实现高伸缩性架构。
- 作为流处理平台, Kafka与其他主流大数据流式计算框架相比,优势有两点:更容易实现端到端的正确性;它自己对于流式计算的定位。
Apache Kafka是消息引擎系统,也是一个分布式流处理平台。 - 除此之外, Katka还能够被用作分布式存储系统。不过我觉得你姑且了解下就好了,我从没有见过在实际生产环境中,有人把Kafka当作持久化存储来用。
应该选择哪种Kafka
- Apache Katka,是开发人数最多、版本速度最快的Kafka,如果你仅仅需要一个消息引擎系统抑或是简单的流处理应用场景,同时需要对系统有较大把控度,那么推荐使用Apache Kafka
- Confluent Kafka, 目前分为免费版和企业版两种。企业版提供了很多功能,最有用的当属跨数据中心备份和集群监控了。如果你需要用到Katka的一些高级特性,那么推荐使用Confluent Kafka.
- CDH/HDP Kafka,如果你需要快速地搭建消息引擎系统,或者你需要搭建的是多框架构成的数据平台且Kafka只是其中一个组件,那么推荐使用这些大数据云公司提供的Katka
Kafka版本号
认识Kafka版本号
官网上下载 Kafka 时,会看到这样的版本
前面的版本号是编译 Kafka 源代码的 Scala 编译器版本。后面的才是kafka的版本。
对于 kafka-2.11-2.1.1
的提法,真正的 Kafka 版本号实际上是 2.1.1。那么这个 2.1.1 又表示什么呢?前面的 2 表示大版本号,即 Major Version
;中间的 1 表示小版本号或次版本号,即 Minor Version
;最后的 1 表示修订版本号,也就是 Patch(补丁)
号。Kafka 版本号从来都是由 3 个部分构成,即大版本号 - 小版本号 - Patch 号
。这种视角可以统一所有的 Kafka 版本命名,也方便我们日后的讨论。假设碰到的 Kafka 版本是 0.10.2.2,你现在就知道了它的大版本是 0.10,小版本是 2,总共打了两个大的补丁,Patch 号是 2。
kafka的版本演进
-
0.7版本:只提供了最基础的消息队列功能。
-
0.8版本:引入了副本机制,至此Kafka成为了一个真正意义上完备的分布式高可靠消息队列解决方案。
-
0.90.0版本:增加了基础的安全认证/权限功能;使用lava重写了新版本消费者API;引入了Katka Connect组件。
-
0.10.0.0版本:引入了Kafka Streams,正式升级成分布式流处理平台。
-
0.11.0.0版本:提供了幂等性Producer API以及事务API;对Kafka消息格式做了重构。
-
1.0和2.0版本:主要还是Kafka Streams的各种改进。