kafka采用的是标准的发布-订阅模型,主要用在异步、解耦的场景、流量控制(削峰填谷)的场景。
生产者和消费者
一个典型的发布订阅系统长这个样子,如图1所示。
图1 发布-订阅模型
在发布 - 订阅模型中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber),服务端存放消息的容器称为主题(Topic)。发布者将消息发送到主题中,订阅者在接收消息之前需要先“订阅主题”。“订阅”在这里既是一个动作,同时还可以认为是主题在消费时的一个逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息。
在kafka中,生产者自己选择发布数据到相应的topics。存储消息的服务器叫broker,一般来说,Kafka集群有多个broker,用来做负载均衡。生产者发布数据也可以采取简单的循环方式进行负载均衡,也可以依据一定的分区策略(比如基于record中的key)。
图2展示了Kafka的整体架构。生产者发布消息到topic,每个topic又分成多个partition,每台服务器(broker)拥有0个或多个topic的partition。每个partition是一个有读写顺序的log文件,存储在硬盘上。
图2 kafka架构图
相比于传统的 发布/订阅 系统,Kafka中的消费者可以看做是一组合作的进程。topic中的每个partition传送给消费者组中的一个消费者。因此,partition的个数是topic的并行个数,也决定了消费者的并行程度 – 个数。
由于broker本身是无状态的,所以需要Zookeeper来维护服务器的状态。在Kafka里把消费者按标签分成消费者组(consumer group),每一条发布到topic的记录被发送到一个消费者组。消费者组中的实例可以在不同的线程或不同的机器上。
每个partition都会对应一个消费者组,消费者组之间是隔离的,partition会为每个消费者组记录当前消费的位置,而消费者组中的消费实例对消息的消费是竞争关系,一个消费者消费的消息,其他消费者就无法再消费了。
保证消息不丢失
一条消息从产生到消息要经历 生产、存储转发、消费 三个过程,要保证消息的不丢失,那在这三个阶段都需要做一些事情,来避免消息的丢失。
图3 消息生产-存储-消费
- 生产阶段: 在这个阶段,从消息在 Producer 创建出来,经过