用户工具


kafka工作流程图

producer

产生消息的客户端,产生的消息发给topic中的某个partition。当然,你可以控制消息具体发到哪个partition(只要实现Partitioner即可)

import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties;

import java.io.PrintWriter;

public class ProducerPartitioner implements Partitioner {

    public ProducerPartitioner(VerifiableProperties props) {

    }
    public int partition(Object key, int numPartitions) {
        
        return Math.abs(key.hashCode() % 3);
    }
}
******************
在JProducer设置自己实现的partition类
props.put("partitioner.class", "ProducerPartitioner");
******************

broker

目的:管理多个partition(这些partition可能来自多个topic)

  • 每个broker 管理多个topic

controller

目的:普通列表项目Kafka选举一个broker作为controller,这个controller通过watch Zookeeper检测所有的broker failure,并负责为所有受影响的parition选举leader,再将相应的leader调整命令发送至受影响的broker.

  • 普通列表项目如果controller失败了,幸存的所有broker都会尝试在Zookeeper中创建/controller→{this broker id},如果创建成功(只可能有一个创建成功),则该broker会成为controller,若创建不成功,则该broker会等待新controller的命令。

topic

目的:管理一类消息

  • topic由多个partition组成(每个partition由多个broker管理)
  • topic和broker没有严格的对应关系
    • 一个broker管理多个topic的多个partition
    • 一个topic的partition被多个broker管理

partition

目的:partition 可以分布在多台机器上(机器间调度的最小单位)。用于分担topic的负载

  • 消息在partition内部是有序的,在partition之间不保证有序

partition leader

  • 每个Partition会有一个Leader,有0个或多个followers. leader处理这个partition的所有读写请求,followers被动的复制leader.

    leader fails,其中一个followers自动成为leader

segment

目的:partition存储的逻辑单位,在文件系统中是一个目录(存在在参数log.dir指定的目录下)

  • 每个partition由多个segment组成
  • 每个Segment,包括了一个数据文件和一个索引文件,下图是某个partition目录下的文件:
  • 索引文件(.index)文件采用的方式存储,减小磁盘空间
    • 稀疏索引:索引文件一条记录对应文件的一个block(粒度大)
    • 稠密索引:索引文件一条记录对应文件中的一行记录(粒度小)

  • 数据查找方式如下

consumer group

目的:管理多个consumer

  • consumer group逻辑上可以理解成一个消费者因为,每条消息只会发给group中的某个consumer(可以利用这个特点并行处理消息)
  • 每个consumer会尽量和topic的每个partition对应起来
    • 在一个group中,如果consumer个数少于partition个数,那会有一些consumer消费多个partition
    • 在一个group中,如果consumer个数等于partition个数,那每个consumer固定消费一个partition
    • 在一个group中,如果consumer个数大于partition个数,那会有一些consumer得不到任何消息
    • 每个partition一段时间只会服务于一个consumer,当consumer挂了或断开连接之后,才会服务于其他consumer

如果有新的consumer加入group,或有旧的consmer挂掉,会导致consumer 和 partition对应关系重新分配

offset维护

所有consumer获取消息时会连接zookeeper。zookeeper保存每个consumer group对其所关注topic的每个分区的offset。这样任何时候consumer group都知道上次访问到哪条消息了。这次接着读取就好了。如下图

  • (topic)有3个partition
  • (consumer group)在test117的第3个分区的offset 是1473(上次访问到test117的第三个partition的第1473条信息)

容错策略