小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
承接上文# 几张图理解kafka的设计原理(一) 本文继续针对kafka的消息发送过程、partition配置规则、partition的leader与follower这些术语和它们的作用简单的用图来解释一下。
消息发送过程
topic相当于传统消息系统MQ中的一个队列queue,producer端发送的消息必须指定是发送到哪个topic,但是不需要指定topic下的哪个partition,因为kafka会把收到的消息进行load balance,均匀的分布在这个topic下的不同的partition上( hash(message) % broker数量)。物理上存储上,这个topic会分成一个或多个partition,每个partiton相当于是一个子queue。
在物理结构上,每个partition对应一个物理的目录(文件夹),文件夹命名是[topicname][partition][序号],一个topic可以有无数多的partition,根据业务需求和数据量来设置。在kafka配置文件中可随时更高num.partitions参数来配置更改topic的partition数量,在创建topic时通过参数指定parittion数量。topic创建之后通过kafka提供的工具也可以修改partiton数量。
partition配置规则
- 一个topic的partition数量大于等于
broker的数量,可以提高吞吐率。 - 同一个
partition的replica尽量分散到不同的机器,高可用。 - 当新增一个
partition的时候,partition里面的消息不会重新进行分配,原来的partition里面的消息数据不会变,新加的这个partition刚开始是空的,随后进入这个topic的消息就会重新参与所有partition的load balance
partition副本
每个partition可以在其他的kafka broker节点上存副本,以便某个kafka broker节点宕机不会影响这个kafka集群。存副本的方式是按照kafka broker的顺序存。例如有3个kafka broker节点,某个topic有3个partition,每个partition存1个副本,那么partition1存broker1,partition2存broker2,以此类推(replica副本数目不能大于kafka broker节点的数目,否则报错。这里的replica数其实就是partition的副本总数,其中包括一个leader,其他的就是copy副本)。
这样如果某个broker宕机,其实整个kafka内数据依然是完整的。但是,副本数越高,系统虽然越稳定,但是回来带资源和性能上的下降;副本少的话,也会造成系统丢数据的风险。
发送消息
producer先把消息发送到partition leader,再由leader发送给其他partition follower。(如果让producer发送给每个replica那就太慢了)
处理某个副本不工作的情况
如果这个不工作的partition replica不在ack列表中,就是producer在发送消息到partition leader上,partition leader向partition follower发送消息没有响应而已,这个不会影响整个系统,也不会有什么问题。如果这个不工作的partition replica在ack列表中的话,producer发送的消息的时候会等待这个不工作的partition replca写消息成功,但是会等到time out,然后返回失败因为某个ack列表中的partition replica没有响应,此时kafka会自动的把这个部工作的partition replica从ack列表中移除,以后的producer发送消息的时候就不会有这个ack列表下的这个部工作的partition replica了。
处理Failed Replica恢复回来的情况
如果这个partition replica之前不在ack列表中,那么启动后重新受zookeeper管理即可,之后producer发送消息的时候,partition leader会继续发送消息到这个partition follower上。如果这个partition replica之前在ack列表中,此时重启后,需要把这个partition replica再手动加到ack列表中。(ack列表是手动添加的,出现某个不工作的partition replica的时候自动从ack列表中移除的)
partition的leader与follower
partition也有leader和follower之分。leader是主partition,producer写kafka的时候先写partition leader,再由partition leader push给其他的partition follower。partition leader与follower的信息受zookeeper控制,一旦partition leader所在的broker节点宕机,zookeeper会从其他的broker的partition follower上选择follower变为parition leader。