1、kafka的设计是什么样的
- kafka将消息以topic为单位进行归纳
- 将数据发送到topic的程序称为生产者,从topic上消费数据的程序称为消费者
- kafka以集群的方式运行,可以有1个或者多个节点,每个节点叫做一个broker
- procucer通过网络将消息发送到kafka集群,集群向消费者提供消息
2、kafka采用pull模式还是push模式
- push模式是指broker主动向消费者发送消息,pull模式是指消费者主动从broker上拉取消息
- kafka采用的是pull的方式
- push方式:当broker的推送速率大于consumer的消费速率的时候,有可能会阻塞或者丢失数据
- pull的好处:consumer可以自主决定是否批量的从broker拉取数据,但是可能会空循环有时候,kafka可以设置延时多长时间后再拉取
3、数据传输的事务定义有哪三种
- 最少一次:消息不会被漏发,最少发送一次
- 最多一次:最多发送一次,消息不会重复
- 精准一次:最少一次+幂等性,不会漏传输也不会多传输,每个消息只会发送一次,且不会丢失
- 幂等性:可以在配置文件中开启,幂等性的实现是这样的,当生产者连接到kafka集群的时候,kafka会分配一个PID,标识生产者ID;生产者发送每条消息的时候会带一个序列化号seqNumber(和offset没关系),broker会以<PID,partition,seqNumber>作为一个key保存该条消息,若下次收到相同的key则不保存
- 幂等性只能解决同一个会话,同一个partition中的数据重复,当生产者重启后会重新生成PID,就算新的数据了
4、名词解释
-
partition:分区,每个partition 自己有独立的偏移量
-
replication:副本,副本里面包括 leader 和 follower,假如副本数为2, 则里面一个leader,一个follower。如果有2个副本,则follower和leader一定不能在同一台上,副本数量不能大于brokker的数量
-
offset:数据偏移量
-
ISR: in-sync replica, 同步副本,和leader保持同步的集合。当ISR中的follower和leader完成数据同步后,leader会给follower发送ack,如果follower长时间未回复leader,则该follower被剔除
- 高版本中加入ISR的条件是依据 follower向leader发送获取数据的的请求时间决定,默认如果10S不发送同步数据的请求则剔除
-
AR: assigned replicas, 所有的副本统称为AR
-
HW: high watermark, 所有副本中最小的LEO,表示消费者能看到的offset,保证消费数据的一致性
-
LEO: log end offset,每个副本中的最后一个offeset
5、小的知识点
- 由于kafka的数据偏移量(读、写),各个partition是独立的,kafka 只保证按一个 partition 中的顺序将消息发给 consumer,不保证一个 topic 的整体(多个 partition 间)的顺序
- 同一个消费者组里面的不同消费者不能同时消费同一个分区
6、数据存储
- 日志文件是存储在 partition/topic下的,然后每个日志文件都是一个数据分片
- 每个日志文件存储的是kafka的数据记录,默认存储时间是168个小时,大小为1个G
- 每个日志文件都有一个对应的index文件,来记录数据的索引
7、kafka分区的好处
- 方便在集群中扩展
- 提高并发,可以以partition为单位进行读写
8、kafka生产消息的流程
- producer先从zookeeper的/broker/…/state节点找到partition的leader
- producer将消息发送给leader
- leader将消息写入本地的log
- follower从leaderpull消息,写入本地的log,再向leader发送ack
- leader收到ISR中所有follower的ack后增加HW,向producer回复ack
9、kafka producer等待ack的级别
- 0:producer不需要等待ack,只发一次数据,可能丢失数据
- 1:producer等待broker的ack, partition的leader落盘后就返回ack,可能丢数据
- -1:所有ISR中的follower全部落盘后返回ack, 极限情况可能丢数据,ISR中只有一个leader则可能丢失数据,但更多是重复数据
10、消费者的分区和消费策略
-
roundRobin: 同一个消费者组中所有消费者消费的topic的所有partition放在一起,然后消费者组中的所有消费者去轮训消费每个partition
- 出现问题: 当 consumerA只消费topicA, consumerB只消费topicB时会出现混乱消费
-
range:按topic进行划分,假如消费者组中有2个消费者C1,C2,消费三个topicTa,Tb,Tc,每个topic有三个分区Ta1,Ta2,Ta3,则C1消费Ta1和Ta2,C2消费Ta3;同样的方式消费Tb和Tc
- 缺点:可能带来消费者消费数据不对等的问题
-
kafka默认是使用的是range,当消费者组中的消费者发生变化后,增加或者减少都会触发重新分区;当触发重新分区时,如果消费者数量多于某个topic的的partition,则会随机选和partition数量相等的消费者消费数据
11、消费偏移量相关
- 消费者组+topic+partition确定某个消费者组在某个话题的某个分区上的消费偏移量
- 在zookeeper中消费偏移量是记录在了文件中,在kafka中消费偏移量是记录在了一个内部topic中(__consumer_offsets),每个消费者对于这个内部的topic来说都是一个生产者,消费者会定时的往该topic提交消费偏移量的数据(即便消费者没有消费到数据)
12、kafka把数据存储在了硬盘上为什么还这么快
-
partition并行处理
-
kafka采用顺序IO将数据写入磁盘,比随机IO快很多,新的数据直接追加在到文件
- 删除数据的时候将 Partition 分为多个 Segment,每个 Segment 对应一个物理文件,通过删除整个文件的方式去删除 Partition 内的数据,这种方式清除旧数据的方式,也避免了对文件的随机写操作
-
即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存,利用操作系统的mmap技术持久化磁盘,利用操作系统的Page Cache 利用内存来提高IO效率。
Memory Mapped Files:简称 mmap,也有叫 MMFile 的,使用 mmap 的目的是将内核中读缓冲区(read buffer)的地址与用户空间的缓冲区(user buffer)进行映射。从而实现内核缓冲区与应用程序内存的共享,省去了将数据从内核读缓冲区(read buffer)拷贝到用户缓冲区(user buffer)的过程- mmap 也有一个很明显的缺陷——不可靠,写到 mmap 中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用 flush 的时候才把数据真正的写到硬盘。Kafka 提供了一个参数——producer.type 来控制是不是主动flush;如果 Kafka 写入到 mmap 之后就立即 flush 然后再返回 Producer 叫同步(sync);写入 mmap 之后立即返回 Producer 不调用 flush 就叫异步(async),默认是 sync。
-
零拷贝技术
-
参考文章:https://zhuanlan.zhihu.com/p/183808742