kafka的设计主要目标
- 以复杂度O(1)的方式提供消息持久化能力,即使对TB级以上的数据也能保证常数的访问性能
- 高吞吐率,即使在非常廉价的商用机器也能做到单机支持秒100k条消息的传输
- 支持Kafka Server间消息分区,及分布式消费,同时保证分区内的消息顺序传输
- 支持离线的数据处理和实时数据处理
- 支持在线水平扩展
为什么使用消息系统
- 解耦
允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
- 冗余
消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
- 扩展性
因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可
- 灵活性和峰值处理能力
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃
- 可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
- 顺序保证性
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(Kafka保证一个Partition内的消息的有序性)
- 缓冲
消息队列通过一个缓冲层来帮助任务最高效率地执行,写入队列的处理尽可能开始。有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
- 异步通信
很多时候,用户不想也不需要立即处理信息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但不立即处理,想要队列中放入多少数据就放多少,然后在需要的时候再去处理
Kafka架构
Kafka集群中将消息以Topic命名的消息队列中,消费者订阅发往某个Topic命名的消息队列queue中的消息
其中Kafka集群由若干个Broker组成,Topic中含有多个Partition,每个Partition中通过Offset来获取
- Producer:消息生产者,即将消息发布到指定的Topic中,同时Producer也能绝对消息所属的Partition
- Consumer:消息消费者,即向指定的Topic获取消息,根据指定的Topic的分区索引及其对应分区上的的消息偏移量来获取消息
- Consumer Group: 消费者组,每一个Consumer属于一个Consumer Group,每一个Consumer Group包含一个或多个Consumer。如果所有的Consumer都具有相同的Consumer Group,那么消息将会在Consumer之间进行负载均衡,这也是传统的消息系统 “队列”模型。也就是说一个Partition中的消息只会被具有相同groupID的Consumer消费,并且每个Consumer Group之间是相互独立的。如果要实现“发布-订阅”模型,则每个消费 者的消费者组名称都不相同,这样每条消息就会广播给所有的消费者。
- Broker:一台Kafka服务器即使一个Broker,一个集群由多个Broker组成,一个Broker可以容纳多个Topic,Broker之间的关系基本是平等的,并不像Hadoop集群那样存在主从模式和为防止单点故障Standby节点
- Topic:每条发送到Kafka集群的消息都属于某个Topic。物理上Topic是分开存储的,逻辑上,用户读写数据时并不需要关心他们是存储到哪里的
- Partition:Kafka集群为了实现可扩展性,一个非常大的Topic可以分成多个Partition,从而分布到多台Broker中。Partition中的每条消息都会分配有一个自增ID(Offset)。Kafka保证一个Partition内的消息的有序,不保证一个Topic的Partition之间有序
- Offset:消息Topic的partition中的位置,同一个Partition中,随着消息的写入,对应Offset自增
- Replica:副本。Topic的Partition含有N个副本。其中一个是Replica的Leader,其他的都是Follower,Leader处理partition的读写请求,与此同时,Follower会定期的去同步Leader上的数据 一主多从
- Message:消息,是通信的结伴单位,每个Producer可以向一个Topic发布一些Message
- Zookeeper:存放Kafka集群的元数据组件。在Zookeeper集群中会保存Topic的状态信息,如分区个数,分区组成,分区分布情况等、保存Broker的状态信息、保存消费者的消费信息等。通过这些信息,Kafka很好地将消息生产、消息存储、消息消费的过程结合起来
Kafka网络拓扑

说明
- Producer根据指定的路由方法(Round-Robin、Hash等),将消息Push到Topic中的某个Partition中
- Kafka集群收到Producer发来的信息后,将其持久化到硬盘,并保留消息的指定时长(可配置),而不关注消息是否被消费
- Consumer从Kafka集群中Pull数据,并控制获取消息的Offset
Kafka的通信过程详解
先说一下KafkaController,它是Broker内部负责管理分区和副本状态以及异常情况下分区重新分配等功能的模块,每个Kafka集群只有一个KafkaController为Leader其他的为Standby,当一个Leader挂掉后,Zookeeper或选举一个新的KafkaController为Leader
一些概念
- Assigned Replicas(AR): 分区中的所有副本数。In-Sync Replicas(ISR): 与Leader副本保持一定程度同步的副本。ISR是AR的子集。”一定程度的同步“是指可忍受的之后范围,这个范围可以通过参数进行配置。与Leader副本滞后过多的副本组成OSR(Out-of_Sync Replicas)。AR=ISR+OSR。 只有只有在ISR中的副本才有资格被选为Leader
- ISR与HW和LEO。HW(High Watermark),俗称高水位,它标识了一个特定的消息偏移量Offset,消费者只能读取这个offset之前的消息。LEO(Log End Offset)它标识当前日志文件下一条待写入消息的offset。LEO的大小相当于当前日志中的最后一条消息的offset加1
- Kafka订单复制机制既不是完全的同步通信也不是单纯的异步通信