文章插图
如上图所示,kafaka集群的 broker,和 Consumer 都需要连接 Zookeeper 。Producer 直接连接 Broker 。
Producer 把数据上传到 Broker,Producer可以指定数据有几个分区、几个备份 。上面的图中,数据有两个分区 0、1,每个分区都有自己的副本:0'、 1' 。
黄色的分区为 leader,白色的为 follower 。
leader 处理 partition 的所有读写请求,与此同时,follower会被动定期地去复制leader上的数据 。如下图所示,红色的为 leader,绿色的为 follower,leader复制自己到其他 Broker 中:
文章插图
如果leader发生故障或挂掉,一个新leader被选举并接收客户端的消息 。Kafka确保从同步副本列表中选举一个副本为 leader 。
关于follower 的同步机制可参考:
https://blog.csdn.net/lizhitao/article/details/51718185
Topic 分区被放在不同的 Broker 中,保证 Producer 和 Consumer 错开访问 Broker,避免访问单个 Broker造成过度的IO压力,使得负载均衡 。
Zookeeper 在 Kafka 中的作用1、Broker注册Broker是分布式部署并且相互之间相互独立,但是需要有一个注册系统能够将整个集群中的Broker管理起来,此时就使用到了Zookeeper 。在Zookeeper上会有一个专门用来进行Broker服务器列表记录的节点:
/brokers/ids
每个Broker在启动时,都会到Zookeeper上进行注册,即到/brokers/ids下创建属于自己的节点,如/brokers/ids/[0...N] 。
Kafka使用了全局唯一的数字来指代每个Broker服务器,不同的Broker必须使用不同的Broker ID进行注册,创建完节点后,每个Broker就会将自己的IP地址和端口信息记录到该节点中去 。其中,Broker创建的节点类型是临时节点,一旦Broker宕机,则对应的临时节点也会被自动删除 。
2、Topic注册在Kafka中,同一个Topic的消息会被分成多个分区并将其分布在多个Broker上,这些分区信息及与Broker的对应关系也都是由Zookeeper在维护,由专门的节点来记录,如:
/borkers/topics
Kafka中每个Topic都会以/brokers/topics/[topic]的形式被记录,如/brokers/topics/login和/brokers/topics/search等 。Broker服务器启动后,会到对应Topic节点(/brokers/topics)上注册自己的Broker ID并写入针对该Topic的分区总数,如/brokers/topics/login/3->2,这个节点表示Broker ID为3的一个Broker服务器,对于"login"这个Topic的消息,提供了2个分区进行消息存储,同样,这个分区节点也是临时节点 。
3、生产者负载均衡由于同一个Topic消息会被分区并将其分布在多个Broker上,因此,生产者需要将消息合理地发送到这些分布式的Broker上,那么如何实现生产者的负载均衡,Kafka支持传统的四层负载均衡,也支持Zookeeper方式实现负载均衡 。
(1) 四层负载均衡,根据生产者的IP地址和端口来为其确定一个相关联的Broker 。通常,一个生产者只会对应单个Broker,然后该生产者产生的消息都发往该Broker 。这种方式逻辑简单,每个生产者不需要同其他系统建立额外的TCP连接,只需要和Broker维护单个TCP连接即可 。但是,其无法做到真正的负载均衡,因为实际系统中的每个生产者产生的消息量及每个Broker的消息存储量都是不一样的,如果有些生产者产生的消息远多于其他生产者的话,那么会导致不同的Broker接收到的消息总数差异巨大,同时,生产者也无法实时感知到Broker的新增和删除 。
(2) 使用Zookeeper进行负载均衡,由于每个Broker启动时,都会完成Broker注册过程,生产者会通过该节点的变化来动态地感知到Broker服务器列表的变更,这样就可以实现动态的负载均衡机制 。
4、消费者负载均衡与生产者类似,Kafka中的消费者同样需要进行负载均衡来实现多个消费者合理地从对应的Broker服务器上接收消息,每个消费者分组包含若干消费者,每条消息都只会发送给分组中的一个消费者,不同的消费者分组消费自己特定的Topic下面的消息,互不干扰 。
5、分区 与 消费者 的关系消费组 (Consumer Group): consumer group 下有多个 Consumer(消费者) 。对于每个消费者组 (Consumer Group),Kafka都会为其分配一个全局唯一的Group ID,Group 内部的所有消费者共享该 ID 。订阅的topic下的每个分区只能分配给某个 group 下的一个consumer(当然该分区还可以被分配给其他group) 。同时,Kafka为每个消费者分配一个Consumer ID,通常采用"Hostname:UUID"形式表示 。
在Kafka中,规定了每个消息分区 只能被同组的一个消费者进行消费,因此,需要在 Zookeeper 上记录 消息分区 与 Consumer 之间的关系,每个消费者一旦确定了对一个消息分区的消费权力,需要将其Consumer ID 写入到 Zookeeper 对应消息分区的临时节点上,例如:
推荐阅读
- 为你揭开玄空飞星风水神秘面纱
- 电饼铛坏了一面还能用吗?电饼铛什么牌子的好
- 螃蟹后面的一坨黄的是什么 螃蟹里面像鸡蛋黄一样的是什么
- 瓷砖表面崩瓷什么原因 瓷砖崩了一点缺口正常吗
- 梦见清水河里抓鱼 梦见清水河里面有很多鱼
- 一文搞懂 Java 线程中断
- 超市卖的全麦面包是真的吗 哪种全麦面包是真的
- 面试 前端面试这些API必须会手写
- 凉席怎样清洗 双面凉席怎么清洗
- 如何挑选虹鳟鱼