1.什么是Kafka
Kafka 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。
(1)消息系统
消息系统负责将数据从一个应用程序传输到另外一个应用程序,使程序之间解耦可以专注于自己的功能。
消息系统有两种消息传递模式:一种是点对点(消息队列),另一种是基于发布-订阅模式。
(2)流处理平台
Kafka 不仅能够与大多数流式计算框架完美整合,并且自身也提供了一个完整的流式处理库,即kafka Streaming。
(3)存储系统
Kafka的消息持久化机制和多副本机制使其能够作为通用数据存储系统来使用。
关键术语
- Producer(生产者):发布消息的对象称之为生产者
- Consumer(消费者):订阅消息并处理发布的消息的对象称之为消费者
- Topic(主题):Kafka将消息分类,每一类的消息称之为一个主题。
- Broker(服务):一个服务器代理点(Broker)。消费者可以订阅一个或多个主题,并从Broker拉数据,从而消费这些已发布的消息
- Partition(分区):每个 topic 都可以分成多个 partition,每个 partition 在存储层面是 append log 文件。一个分区可以分布在不同的服务器(Broker)上,所以一个主题可以横跨多个服务器。
- Offset(偏移量):消息在分区中的唯一标识,Kafka通过它来保证消息在分区内的有序性。不过offset不跨分区,所以Kafka只能保证分区有序而不是主题有序。
- leader和follower副本:Kafka引入了多副本(Replica)机制,副本之间是“一主多从”的关系,leader主副本负责读写请求,follower副本只负责和主副本之间的消息同步。当leader副本故障后,会通过选举机制从follower副本中选举出新的leader副本。
- AR(Assigned Replicas):分区中的所有副本,AR=ISR+OSR。
- ISR(In-Sync Replicas):分区中所有与leader副本保持一定程度同步的副本(包括leader副本)组成ISR。
- OSR(Out-of-Sync Replicas):与leader副本同步之后过多的副本(不包括leader副本)组成OSR,正常情况下OSR集合为空,并且默认情况下OSR的副本没有资格参与选举。
- HW(High Watermark):高水位,它标识了一个特定的消息offset,消费者只能拉去到这个offset之前到消息。
-
LEO(Log End Offset):它标识当前日志文件中下一条消息到offset。LEO相当于当前日志分区中最后一条消息的offset+1,分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW。
分区和主题
每一个分区都是一个顺序的、不可变的消息队列, 并且可以持续的添加。分区中的消息都被分了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。
Kafka集群保持所有的消息,直到它们过期(无论消息是否被消费)。实际上消费者所持有的仅有的元数据就是这个offset(偏移量),也就是说offset由消费者来控制:正常情况当消费者消费消息的时候,偏移量也线性的的增加。但是实际偏移量由消费者控制,消费者可以将偏移量重置为更早的位置,重新读取消息。可以看到这种设计对消费者来说操作自如,一个消费者的操作不会影响其它消费者对此log的处理。
Kafka中采用分区的设计有几个目的。一是可以处理更多的消息,不受单台服务器的限制。Topic拥有多个分区意味着它可以不受限的处理更多的数据。第二,分区可以作为并行处理的单元。
通过并行topic的parition —— kafka提供了顺序保证和负载均衡。每个partition仅由同一个消费者组中的一个消费者消费到。并确保消费者是该partition的唯一消费者,并按顺序消费数据。每个topic有多个分区,则需要对多个消费者做负载均衡,但请注意,相同的消费者组中不能有比分区更多的消费者,否则多出的消费者一直处于空等待,不会收到消息。
消费模型
通常来讲,消息模型可以分为两种, 队列和发布-订阅式。 队列的处理方式是 一组消费者从服务器读取消息,一条消息只有其中的一个消费者来处理。在发布-订阅模型中,消息被广播给所有的消费者,接收到消息的消费者都可以处理此消息。Kafka 为这两种模型提供了单一的消费者抽象模型: 消费者组 (consumer group)。
消费组(Consumer Group)是Kafka的消费理念中一种特有的概念,每个消费者都属于一个消费组。生产者的消息发布到主题后,只会被投递给订阅该主题的每个消费组中的一个消费者。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;所有的消费者都有一个与之对应的消费者组,即消费者组是逻辑上的一个订阅者。消费者组之间互不影响,多个不同的消费者组可以同时订阅一个Topic,此时消息会同时被每个消费者组中一个消费者消费。
2个kafka集群托管4个分区(P0-P3),2个消费者组,消费组A有2个消费者实例,消费组B有4个。
注意:Kafka的Consumer使用拉(Pull)模式从服务端拉取消息,并保存消费的具体位置。这样当消费者宕机恢复上线后可以根据之前保存的消费位置重新拉取需要的消息进行消费,这样就不会造成消息丢失。
补充
消息系统的两种传递模式
在点对点的消息传递域中,目的地被称为队列(queue)
在发布订阅消息传递域中,目的地被称为主题(topic)
MQ消息常见的两种消费方式
Pull模式
(1)消费过程
- 消费端采用轮询的方式,从mq服务中拉取消息进行消费
- 消费完成通知mq删除已消费成功的消息
- 继续拉取消息消费
(2)优点
- 消费者可以根据自己的性能主动控制消息拉去的速度,控制自己的压力
- 实时性相对于push方式会低一些
- 消费者属于主动方,控制权更大一些
(3)缺点
- 消费方需要实现消息拉取的代码
- 消费速度较慢时,可能导致mq中消息积压,消息消费延迟等
Push模式
(1)消费过程
- mq接收到消息
- mq主动将消息推送给消费者(消费者需提供一个消费接口)
(2)优点
- 消费者代码较少:对于消费者来说,只需提供一个消费接口给mq即可;mq将接收到的消息,随即推送到指定的消费接口
- 消息实时性比较高:对于消费者来说,消息一旦到达mq,mq会立即推送给消费者
(3)缺点
- 消费者属于被动方,消息量比较大时,对消费者性能要求比较高;若消费者机器资源有限,可能会导致压力过载,引发宕机的情况。
- 对消费者可用性要求比较高:当消费者不可用时,会导致很push失败,在mq方需要考虑至少推送成功一次。
参考文献
kafka详细教程
Apache Kafka 基础
kafka入门介绍
谈谈mq消息消费的几种方式
深入理解Kafka核心设计与实践原理–朱忠华