producer 即生产者,生产者可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。
可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(例如:记录中的key)来完成。下面会介绍更多关于分区的使用
consumer即消费者,消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例.消费者实例可以分布在多个进程中或者多个机器上。
如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例.
如果所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程.
如图,这个 Kafka 集群有两台 server 的,四个分区(p0-p3)和两个消费者组。消费组A有两个消费者,消费组B有四个消费者。
通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个"逻辑订阅者"。一个消费组由许多消费者实例组成,便于扩展和容错。这就是发布和订阅的概念,只不过订阅者是一组消费者而不是单个的进程。
在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。
如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。
Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求。但如果你需要总记录在所有记录的上面,可使用仅有一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程。
Broker:服务代理节点。Broker可以简单的看作一个独立的KAFKA服务节点或kafka服务实例。大多数情况下也可以将Broker看作一台kafka服务器,前提是这台服务器只有一个kafka实例。多个broker组成一个kafka集群。
KAFKA中的消息以主题为单位进行归类,生产者负责将消息发送到特定的主题,而消费者负责订阅主题并进行消费。
Topic 就是数据主题,是数据记录发布的地方,可以用来区分业务系统。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。
对于每一个topic, Kafka集群都会维持一个分区日志,如下所示:
事实上,在每一个消费者中唯一保存的元数据是offset(偏移量)即消费在log中的位置.偏移量由消费者所控制:通常在读取记录后,消费者会以线性的方式增加偏移量,但是实际上,由于这个位置由消费者控制,所以消费者可以采用任何顺序来消费记录。例如,一个消费者可以重置到一个旧的偏移量,从而重新处理过去的数据;也可以跳过最近的记录,从"现在"开始消费。
这些细节说明Kafka 消费者是非常廉价的—消费者的增加和减少,对集群或者其他消费者没有多大的影响。比如,你可以使用命令行工具,对一些topic内容执行 tail操作,并不会影响已存在的消费者消费数据.
主题是一个逻辑上的概念,他还可以细分为多个分区,一个分区只属于单个主题。同一主题下的不同分区包含的消息是不同的,分区在存储层面可以看作是一个可追加的日志(LOG)文件,消息在被追加到分区日志文件的时候都会分配一个特定的偏移量(offset),offset是消息在分区中的唯一标识,kafka通过它来保证消息在分区内的顺序性,不过offset并不跨越分区,也就是说,kafka保证的是分区有序而不是主题有序。
Kafka的replication复制机制是其可靠性的保证,即为每个分区数据提供多个副本。
每个Kafka topic包含有多个分区,分区是kafka存储数据的基本单位。一个分区只能存储在同一个硬盘上。
Kafka保证每一个分区内的消息的顺序,无论这个分区是在线(available)的还是离线的(unavailable)。
每个分区拥有多个副本,其中一个副本将被指定为主副本(leader replicas),其余的为跟随副本(follower)
所有的消息都会写入到主副本,所有的消息都从主要副本读取,其他的副本只需要保持于主副本同步即可
当主副本离线时,其他的副本中的一个将会被推选为新的主副本(一般为该分区副本列表的下一个副本)
关于副本是否处于“同步中(in-sync)”的状态的判断标准:
如果它是主副本,那么它是处于“同步中(in-sync)”的状态。
如果它是跟随副本, 且拥有以下状态,那么它处于“同步中(in-sync)”:
它与zookeeper有一个可用的session(在最近6秒内给zk发送过心跳)
它在最近10秒内从主副本获取过消息
它在最近10秒从主副本获取过最新的消息
否则,该副本的状态为“不同步(out-of-sync)”
当一个同步中的副本出现延迟时,它会影响生产者和消费者的性能。因为只有在所有跟随副本同步完所有消息并且提交后,它们才会继续执行。
kafka不是完全同步,也不是完全异步,是一种特殊的ISR(In Sync Replica)
leader会维持一个与其保持同步的replica集合,该集合就是ISR,每一个partition都有一个ISR,它是由leader动态维护。
我们要保证kafka不丢失message,就要保证ISR这组集合存活(至少有一个存活),并且消息commit成功。
所以我们判定存活的概念时什么呢?分布式消息系统对一个节点是否存活有这样两个条件判断:第一个,节点必须维护和zookeeper的连接,zookeeper通过心跳机制检查每个节点的连接;第二个,如果节点是follower,它必要能及时同步与leader的写操作,不是延时太久。
如果满足上面2个条件,就可以说节点时“in-sync“(同步中的)。leader会追踪”同步中的“节点,如果有节点挂了,卡了,或延时太久,那么leader会它移除,延时的时间由参数replica.log.max.messages决定,判断是不是卡住了,由参数replica.log.time.max.ms决定。
分区中所有副本统称AR(Assigned Replicas)。所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-sync-replicas),ISR集合是AR集合的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间follower副本相对于leader副本有一定程度的滞后。与leader副本同步滞后过多的副本(不包含leader副本)组成OSR(out-of-sync replicas),由此可见AR=ISR+OSR。在正常情况下,所有的follower应该与leader保持一定程度的同步,即AR=ISR,OSR为空集合。
leader副本负责维护和跟踪ISR集合中所有的follower副本的之后状态,当follower副本落后太多或者失效时,leader会把它从ISR中剔除。如果OSR中有副本追上leader副本,那么leader副本会把它从OSR集合中转移到ISR集合。默认情况下,当leader副本发生故障时,只有ISR集合中的副本才有资格参与选举,而OSR集合中的副本则没有任何机会(不过这个策略可以通过参数配置来更改)。
HW即high watermark,俗称高水位,他标识了一个特定的消息偏移量,消费者只能拉取到这个offset之前的数据。
LEO是log end offset的缩写,它标识当前日志文件中下一条待写入消息的offset。
对于同一个副本对象而言,其HW值不会大于LEO值。小于等于HW值的所有消息都被认为是“已备份”的(replicated)。
上图中,HW值是7,表示位移是0~7的所有消息都已经处于“已备份状态”(committed),而LEO值是15,那么8~14的消息就是尚未完全备份(fully replicated)——为什么没有15?因为刚才说过了,LEO指向的是下一条消息到来时的位移,故上图使用虚线框表示。我们总说consumer无法消费未提交消息。这句话如果用以上名词来解读的话,应该表述为:consumer无法消费分区下leader副本中位移值大于分区HW的任何消息。这里需要特别注意分区HW就是leader副本的HW值。
Kafka 中文文档 - ApacheCN
《深入理解Kafka核心设计与实践理论》