====== 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]]