kafka工作流程分析-生产过程

kafka工作流程分析-生产过程_第1张图片

 

Kafka 生产过程分析
写入方式

producer 采用推(push)模式将消息发布到 broker每条消息都被追加(append)到分区(patition)中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障 kafka 吞吐率)。


分区(Partition)
消息发送时都被发送到一个 topic,其本质就是一个目录,而 topic 是由一些 Partition Logs(分区日志)组成,其组织结构如下图所示:

kafka工作流程分析-生产过程_第2张图片

kafka工作流程分析-生产过程_第3张图片

我们可以看到,每个Partition 中的消息都是有序的,生产的消息被不断追加到Partition log 上,其中的每一个消息都被赋予了一个唯一的 offset 值。
1)分区的原因
(1)方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个
topic 又可以有多个 Partition 组成,因此整个集群就可以适应任意大小的数据了;

(2)可以提高并发,因为可以以 Partition 为单位读写了。


2)分区的原则
(1)指定了 patition,则直接使用
(2)未指定 patition 但指定 key,通过对 key 进行 hash 出一个 patition
(3)patition 和 key 都未指定,使用轮询选出一个 patition

DefaultPartitioner 类
public int partition( String topic, Object key, byte[] keyBytes, Object value, byte[]
			      valueBytes, Cluster cluster )
{
		List	partitions=cluster.partitionsForTopic(topic);
		int	numPartitions = partitions.size();
		if (keyBytes == null )
		{
			int	nextValue = nextValue( topic );
			List	availablePartitions	=
				cluster.availablePartitionsForTopic( topic );
			if (availablePartitions.size() > 0 )
			{
				int part = Utils.toPositive( nextValue ) % availablePartitions.size();
				return(availablePartitions.get( part ).partition() );
			} else {
				/* no partitions are available, give a non-available partition */
				return(Utils.toPositive( nextValue ) % numPartitions);
			}
		} else {
			/* hash the keyBytes to choose a partition */
			return(Utils.toPositive( Utils.murmur2( keyBytes ) ) % numPartitions);
		}
}


副本(Replication)
同一个 partition 可能会有多个 replication ( 对 应 server.properties 配置中的default.replication.factor=N)。没有 replication 的情况下,一旦 broker 宕机,其上所有patition 的数据都不可被消费,同时 producer 也不能再将数据存于其上的 patition。引入replication 之后,同一个partition 可能会有多个replication,而这时需要在这些replication 之间选出一个leaderproducer 和consumer 只与这个leader 交互,其它replication 作为follower 从 leader 中复制数据。


写入流程
producer 写入消息流程如下:

kafka工作流程分析-生产过程_第4张图片

1)producer 先从 zookeeper 的 "/brokers/.../state"节点找到该 partition 的 leader
2)producer 将消息发送给该 leader
3)leader 将消息写入本地 log
4)followers 从 leader pull 消息,写入本地 log 后向 leader 发送 ACK
5)leader 收到所有 ISR 中的 replication 的 ACK 后,增加 HW(high watermark,最后 commit的 offset)并向 producer 发送 ACK
 

你可能感兴趣的:(#,kafka)