简介:Kafka是由Linkedin(领英)开发的一个分布式、分区多副本、多订阅者、基于Zookeeper协调的分布式日志/MQ系统,于2010年贡献给Apache基金会并成为顶级开源项目。
Kafka的特性
# 1、高吞吐、低延迟
kafka最大的特点就是收发消息非常快,kafka每秒可以处理百万级别的消息,最低延迟只有几毫秒
# 2、高伸缩性
每个主题(topic)包含多个分区(partition),主题中的分区可以分布在不同的主机(broker)中
# 3、持久性、可靠性
kafka能够允许数据的持久化存储,消息被持久化到磁盘,并且支持数据备份防止丢失,kafka底层的数据存储是基于Zookeeper存储的(Zookeeper的数据能够持久存储)
# 4、容错性
允许集群中的节点失败,某个节点宕机,kafka集群能够正常工作
# 5、高并发
支持数千个客户端同时读写
高吞吐
1、顺序写磁盘
2、零复制技术(使用零拷贝原理来快速移动数据,避免了内核之间的切换)
3、消息压缩
4、分批发送
数据可靠性的保证
ACK应答机制+副本同步机制+ISR
消息传递模式主要有两种:点对点传递模式、发布-订阅模式
kafka在生产者是push消息、而消费者是pull消息
kafka基础框架
Producer:生产者,消息的入口
Broker:kafka实例
Topic:消息的主题
Partition:Topic的分区(分区的作用是做负载,提高kafka的吞吐量,同一个topic在不同分区的数据是不重复的,partition表现形式是一个一个的文件夹)
Replication:每个分区都有多个副本,副本的作用是做备胎,当主分区(Leader)故障的时候就会选择一个备胎(Follower)上位成为Leader,默认副本最大数量是10个,且不能大于Broker数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)
Message:消息主体
Consumer:消费者,消息的出口
Zookeeper:kafka集群依赖zookeeper来保存集群的元信息,来保证系统的可用性
工作流程
(1)发送数据
Producer在写入数据的时候永远的找leader,不会直接将数据写入follower!
重要:producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!
重要:producer向kafka写入消息是通过ACK应答机制来保证消息不丢失的(级别0 1 all)
重要:partition分为多组segment,每个segment中又包含.log、.index、。timeindex文件,存放的每条message中包含offset、消息大小、消息体
假如现在需要查找一个offset为368801的message是什么样的过程呢?
1、先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。
2、打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系,所以直接找相对offset为5的索引找不到,这里同样利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。
3、根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。
这套机制是建立在offset为有序的基础上,利用segment+有序offset+稀疏索引+二分查找+顺序查找等多种手段来高效的查找数据!至此,消费者就能拿到需要处理的数据进行处理了。
(2)消费数据
读取数据的时候也是找leader去拉取,同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据,所以消费者多于partition是提效不了的,实际开发中,一般建议消费组的consumer和partition数量一致
重要 如何保证消息消费有序——>指定分区和用单一消费者消费分区保证顺序
一些项目中使用kafka的小坑:
Kafka包中的消费者的自动提交不能单独使用,enable-auto-commit单独使用是无效的,即单独配置,无论配置成true/false最终都会自动提交offset。
(1)enable-auto-commit是为手动提交设置的;
(2)Ack手动提交,配置消费者enable-auto-commit: false和手动提交ack-mode: manual,此时,在消费者中手动ack。
标签:--,分区,kafka,查找,MQ,消息,offset,Kafka,segment
From: https://www.cnblogs.com/kris-cbl/p/18363418