Kafka是一个分布式消息队列,为处理实时数据提供一个统一、高吞吐量、低等待的平台,提供了类似于JMS的特性,但是它并不是JMS规范的实现.
JMS消息传输模型
1.点对点模式
2.发布/订阅模式(类似于kafka)
生产者消费者模式:Producer->Topic->consumer
ps:消费者组(Consumer Group)才是逻辑上的订阅者
无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息。
Kafka文件存储结构:
一台Kafka服务器就是一个broker,一个broker中有若干个topic,每个topic中有若干partition,所有partition中都有segment分段,每个segment都包含两个文件:index文件和log文件。
broker->topic->partition->segment->index+log
Kafka解决了传统MQ(MessageQueue)的问题,有别于传统MQ的新特征:
- 异步处理
- 消峰
- 解耦
一、kafka的partition管理
- kafka提供高可用,每个partition有若干副本,存放在不同节点上,也就是不同broker上。
- 为了方便管理,kafka提供了副本选举机制,由leader同步数据到所有follower。
- kafka还提供了partition出错恢复机制,包括leader出错以及follower出错两种情况,
当leader出错之后,kafka会重新选择序列号最小的follower作为新的leader,然后将其他follower中HW之后的数据整合到新的leader中。
当follower出错之后,由leader恢复HW之前的数据,HW之后的数据丢失,然后同步数据直到达到leader的LEO,添加到ISR中。
HW(High Water):leader中的HW是所有副本中最小的LEO,代表所有partition同步完成的数据量
LEO(Log End Offset):每个副本最后一个offset的位置
二、ACK应答机制
producer会向leader发送数据,leader接收数据之后需要返回一个信息确认信息,这个确认信息就是ack。
1.ack=0
leader收到信息之后,在落地磁盘之前,就返回ack。
这种方式延迟会降低,但是出现异常状态,容易丢失数据。
2.ack=1
leader收到信息之后,将数据落地磁盘,之后返回ack。
在未同步完数据之前就返回ack,如果leader出错,副本数据会丢失。
3.ack=all
leader收到信息之后,将数据落地磁盘,数据同步到所有副本中,最后返回ack。
这种方式虽然数据不容易丢失,但也存在数据重复的可能性,假如leader同步完数据之后,在发送ack之前出错,follower中会选举出新的leader,同时producer接收不到ack,会重新发送数据到新的leader,新的leader就有了两份一摸一样的数据。
三、ISR数据同步机制
ISR相当于一个数组列表,里面包含所有follower以及leader自身,初始状态所有的副本都处于ISR中,当一个消息发送给leader的时候,leader会等待ISR中所有的副本告诉它已经接收了这个消息,如果一个副本失败了,那么它会被移除ISR。下一条消息来的时候,leader就会将消息发送给当前的ISR中节点了。
四、kafka消息快速存储的底层实现
读写磁盘
不同于Redis和传统MQ等内存消息队列,Kafka的设计是把所有的Message都要写入速度低容量大的硬盘,以此来换取更强的存储能力,事实上这种设计并没有带来更多的性能损耗。
顺序读写
kafka在磁盘上只做顺序读写,顺序读写的效率要比随机读写高很多,因为只做顺序读写,所有规避了磁盘访问速度低下对性能可能造成的影响。
PageCache
Kafka依赖底层操作系统提供的PageCache功能,当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。使用PageCache功能同时可以避免在JVM内部缓存数据,不受GC的控制。
Sendfile
Kafka为了进一步的优化性能还采用了Sendfile技术,简化了传统网络I/O操作。
五、如何消费已经消费过的数据
我们知道offset记录consumer group消费的信息,一般情况下消费者组不能直接消费已经消费过的数据。我们可以采取以下两种方式间接消费相同的数据。
1.我们可以将消费者移到新的消费者组中去消费,在consumer挂掉或者新增consumer的情况下会触发kafka负载均衡重新分配所有consumer,形成新的消费者组。
2.通过一些配置,就可以将线上产生的数据同步到镜像中去,然后再由特定的集群区处理大批量的数据。
六、消费者组和分区的关系
消费者组订阅主题,主题下的所有分区都被消费。基于此,消费者组和分区关系如下:
- 分区数=消费者数,一个消费者分区的关系一一对应。
- 分区数>消费者数,出现一个消费者消费多个分区。
- 分区数<消费者数,出现有的消费者空闲的情况。
如果多个消费者负责一个分区会导致资源浪费,消息处理重复,不能保证消息的顺序的问题。
七、zookeeper在kafka中的作用
- 配置管理
- 负载均衡
- 命名服务
- 分布式通知(分区增加,topic变动,Broker上线下线等)
- 集群管理和master选举
- 分布式锁(用于Controller的选举)
网友评论