- 基本概念
- Broker:Kafka节点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
- Topic:一类消息,消息存放的目录即主题,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发。
- Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列
- Segment:partition物理上由多个segment组成,每个Segment存着message信息
- Producer : 生产message发送到topic
- Consumer : 订阅topic消费message, consumer作为一个线程来消费
- Consumer Group:一个Consumer Group包含多个consumer
- Kafka特性:
- 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作。
- 可扩展性:kafka集群支持热扩展
- 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
- 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
- 高并发:支持数千个客户端同时读写
- Broker
- broker之间的关系:不是主从关系,各个broker在集群中地位一样,我们可以随意的增加或删除任何一个broker节点。
- 主从选举:
- 所有的Kafka Broker节点一起去Zookeeper上注册一个临时节点,因为只有一个Kafka Broker会注册成功,其他的都会失败,所以这个成功在Zookeeper上注册临时节点的这个Kafka Broker会成为Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。(这个过程叫Controller在ZooKeeper注册Watch)。
- 主服务挂掉后选举:这个Controller会监听其他的Kafka Broker的所有信息,如果这个kafka broker controller宕机了,在zookeeper上面的那个临时节点就会消失,此时所有的kafka broker又会一起去Zookeeper上注册一个临时节点,因为只有一个Kafka Broker会注册成功,其他的都会失败,所以这个成功在Zookeeper上注册临时节点的这个Kafka Broker会成为Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。
- 服务挂掉:一旦有一个broker宕机了,这个kafka broker controller会读取该宕机broker上所有的partition在zookeeper上的状态,并选取ISR列表中的一个replica作为partition leader(如果ISR列表中的replica全挂,选一个幸存的replica作为leader; 如果该partition的所有的replica都宕机了,则将新的leader设置为-1,等待恢复,等待ISR中的任一个Replica“活”过来,并且选它作为Leader;或选择第一个“活”过来的Replica(不一定是ISR中的)作为Leader),这个broker宕机的事情,kafka controller也会通知zookeeper,zookeeper就会通知其他的kafka broker。
- 生产者
- Producer向Topic发送message,不需要指定partition,直接发送就好了
- producer可以有任意多的thread,这些kafka服务器端是不care的
- Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管从broker pull消息,两者对消息的生产和消费是异步的
- Kafka支持以消息集合为单位进行批量发送,以提高push效率
- 消息投递可靠性(acks)
- acks=0:如果设置为零,那么生产者将不会等待来自服务器的任何确认。 该记录将立即添加到socket缓冲区并视为已发送。 在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障)。 为每条记录返回的偏移量始终设置为-1。
- acks=1:这将意味着主服务将记录写入其本地日志,但无需等待所有从服务的完全确认即可做出回应。 在这种情况下,如果主服务在确认记录后立即失败,但在从服务复制之前,则记录将丢失。
- acks=all:这意味着主服务将等待整套同步副本以确认记录。 这保证了只要至少一个同步副本仍然存活,记录就不会丢失。 这是最强有力的保证。 这相当于acks = -1设置。
- 当生产者将acks设置为“all”(或“-1”)时,min.insync.replicas指定必须确认写入被认为成功的最小副本数。 如果无法满足此最小值,则生产者将引发异常(NotEnoughReplicas或NotEnoughReplicasAfterAppend)。当一起使用时,min.insync.replicas和acks允许您强制执行更大的持久性保证。 典型的情况是创建复制因子为3的主题,将min.insync.replicas设置为2,并使用“all”的acks生成。 如果大多数副本没有收到写入,这将确保生产者引发异常。
- topic
- topic相当于传统消息系统MQ中的一个队列queue,producer端发送的message必须指定是发送到哪个topic
- Partition
- Partition的概念:
- 物理上存储上,这个topic会分成一个或多个partition,每个partiton相当于是一个子queue。
- 在物理结构上,每个partition对应一个物理的目录(文件夹),文件夹命名是[topicname]_[partition]_[序号],一个topic可以有无数多的partition,根据业务需求和数据量来设置
- Partition的数量新增:
- partition里面的message不会重新进行分配,原来的partition里面的message数据不会变,新加的这个partition刚开始是空的,随后进入这个topic的message就会重新参与所有partition的load balance
- Partition的分片复制:
- 每个partition可以在其他的kafka broker节点上存副本,以便某个kafka broker节点宕机不会影响这个kafka集群。
- replica副本数目不能大于kafka broker节点的数目,否则报错。这里的replica数其实就是partition的副本总数,其中包括一个leader,其他的就是copy副本
- replica副本数越高,系统虽然越稳定,但是回来带资源和性能上的下降;replica副本少的话,也会造成系统丢数据的风险。
- Partition的主从:
- 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。
- Partition的消息分配算法:
- 将Broker(size=n)和待分配的Partition排序。
- 将第i个Partition分配到第(i%n)个Broker上。
- 将第i个Partition的第j个Replica分配到第((i + j) % n)个Broker上
- Partition的挂机:
- 如果这个不工作的从partition不在ack列表中,producer在发送消息到partition leader上,partition leader向partition follower发送message没有响应而已,这个不会影响整个系统,也不会有什么问题
- 如果这个不工作的从partition在ack列表中的话,producer发送的message的时候会等待这个不工作的partition replca写message成功,但是会等到time out,然后返回失败因为某个ack列表中的partition replica没有响应,此时kafka会自动的把这个部工作的partition replica从ack列表中移除,以后的producer发送message的时候就不会有这个ack列表下的这个部工作的partition replica了。
- Partition的恢复
- 如果这个partition replica之前不在ack列表中,那么启动后重新受Zookeeper管理即可,之后producer发送message的时候,partition leader会继续发送message到这个partition follower上
- 如果这个partition replica之前在ack列表中,此时重启后,需要把这个partition replica再手动加到ack列表中。(ack列表是手动添加的,出现某个部工作的partition replica的时候自动从ack列表中移除的)
- 修改数量
- 在kafka配置文件中可随时更高num.partitions参数来配置更改topic的partition数量,
- 在创建Topic时通过参数指定parittion数量。
- Topic创建之后通过Kafka提供的工具也可以修改partiton数量。
- Partition的概念:
- Message
- Message的状态
- 消息的状态被保存在consumer中,broker不会关心哪个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着如果consumer处理不好的话,broker上的一个消息可能会被消费多次。
- 持久化
- Kafka中会把消息持久化到本地文件系统中,并且保持o(1)极高的效率。这是因为Kafka是顺序写入o(1)的时间复杂度,速度非常快。也是高吞吐量的原因。
- 由于message的写入持久化是顺序写入的,因此message在被消费的时候也是按顺序被消费的,保证partition的message是顺序消费的。一般的机器,单机每秒100k条数据。
- 有效期
- Kafka会长久保留其中的消息,以便consumer可以多次消费,当然其中很多细节是可配置的。
- Message的状态
- 消费者
- 消费者组
- 各个consumer(consumer 线程)可以组成一个组(Consumergroup),partition中的每个message只能被组(Consumer group)中的一个consumer(consumer线程)消费,如果一个message可以被多个consumer(consumer 线程)消费的话,那么这些consumer必须在不同的组。
- 负载均衡以及触发条件
- Consumer增加或删除
- Broker的增加或者减少
- Consumer与partition
- consumer thread数量大于partition数量:这个consumer thread也会去消费所有的partition。
- consumer group下的consumerthread的数量等于partition数量:这样效率是最高的。
- 当consumer group里面的consumer数量大于partition数量:多余的几个消费线程会空闲
- 消费者组