====== kafka工作流程图 ====== {{:pasted:20150919-142826.png}} ===== 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(粒度大) * 稠密索引:索引文件一条记录对应文件中的一行记录(粒度小) {{:pasted:20150919-105025.png}} * 数据查找方式如下{{:pasted:20150919-105251.png}} ===== 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都知道上次访问到哪条消息了。这次接着读取就好了。如下图 {{:pasted:20150919-151735.png}} * **test117** (topic)有3个partition * **group1** (consumer group)在test117的第3个分区的offset 是1473(上次访问到test117的第三个partition的第1473条信息) ====== 容错策略 ====== [[分布式HA和Failover]]