16、kafka是如何做到高效读写
-
kafka无论发布还是订阅都需要只想topic,每个topic都有一个或多个partition,不同partition可能位于不同节点上。可以充分利用集群的优势,并行处理。
-
kafka的每个分区是有序的,不可变的消息队列。顺序读写速度要远远大于随机读写速度。partition中又分为了多个Segment,每个Segment对应一个文件,直接删除文件的方式删除旧节点,也避免了对文件的随机写操作。
-
充分利用了page cache。page cache的好处I/O Schduler会将小内容组成大内容后在写入,提高性能;还会再写操作时重新排好序,而且cache是内存读写速度本身就很快。Broker收到数据后,会将数据先将数据写入page cache,从而提高效率。
4. kafka采用了零拷贝技术
5. Producer 生产的数据持久化到 broker,采用 mmap 文件映射,实现顺序的快速写入
6. Customer 从 broker 读取数据,采用 sendfile,将磁盘文件读到 OS 内核缓冲区后,转到 NIO buffer进行网络发送,减少 CPU 消耗
- 使用压缩
17、Kafka集群中数据的存储是按照什么方式存储的?
kafka采用了分片和索引机制,将每个partition分为多个segment,每个segment包括:“.index”文件、“.log”文件和“.timeindex”文件等。这些文件放在命名为“topic名称+分区序号”的文件。
18、kafka中是如何快速定位到一个offset的。
-
根据目标offset定位segment文件
-
找到小于等于目标offset的最大offset对应的索引项
-
定位到log日志
-
向下遍历找到目标record
19、简述kafka中的数据清理策略。
Kafka 中默认的日志(这个地方是数据的意思,就是Segment)保存时间为 7 天,可以通过调整如下参数修改保存时间。
log.retention.hours,最低优先级小时,默认 7 天。
log.retention.minutes,分钟。 --如果设置了该值,小时的设置不起作用。
log.retention.ms,最高优先级毫秒。 --如果设置了该值,分钟的设置不起作用。
log.retention.check.interval.ms,负责设置检查周期,默认 5 分钟。
那么日志一旦超过了设置的时间,怎么处理呢?
Kafka 中提供的日志清理策略有 delete 和 compact 两种。
1)delete 日志删除:将过期数据删除
log.cleanup.policy = delete 所有数据启用删除策略
(1)基于时间:默认打开。以 segment 中所有记录中的最大时间戳作为该文件时间戳。
(2)基于大小:默认关闭。超过设置的所有日志总大小,删除最早的 segment。
log.retention.bytes,默认等于-1,表示无穷大。
20、消费者组和分区数之间的关系是怎样的?
一个消费者组中的多个消费者,可以看作一个整体,一个组内的多个消费者是不可能去消费同一个分区的数据的,要不然就消费重复了。
21、kafka如何直到哪个消费者消费哪个分区?
生产者把数据发送给各个分区,每个broker节点都有一个coordinator(协调器),消费者组对分区进行消费,到底哪个消费者消费哪个分区呢?首先groupId对50取模,看最后的结果是哪个分区节点,假如是1分区,那么1分区的协调器就是本次消费者组的老大,消费者纷纷向该协调器进行注册,协调器从中随机选择一个消费者作为本次消费的Leader,然后把本次消费的具体情况发送给Leader,让其制定一个消费计划(就是哪个消费者消费哪个分区),然后Leader发送给协调器,协调器再进行群发,将计划公布,各个消费者按照这个计划进行消费。
22、kafka消费者的消费分区策略有哪些,默认是个?
Kafka 有四种主流的分区分配策略: Range 、 RoundRobin 、 Sticky 、 CooperativeSticky 。
可以通过配置参数 partition.assignment.strategy ,修改分区的分配策略。默认策略是 Range + CooperativeSticky 。 Kafka 可以同时使用 多个分区分配策略。
23、kafka中的消费者,他们的偏移量存储在哪里?
__consumer_offsets 主题
24、kafka中数据挤压太多,怎么办?(提高消费者的效率)
- 增加分区partitions数,但是partition的数量并不是无限增大的,他是有上限的,一般partition的分区数的数不能大于kafka的broker数,因为我做过测试,当分区数大于broker数的时候,会出现无法消费数据的情况
2. 高消费的速度,对于分区数一定的情况下,为了避免单线程的消费一个分区的数据,我们可以多线程去消费分区的数据,这样从而提高kafka的消费者的消费性能,但是对于多线程,此时就需要手动去维护每个分区的offset这个偏移量了。
25、Kafka中的数据在消费过程中,有漏消费和重复消费的情况,怎么办?
通过配置:
同步:producer.type=sync
request.required.acks=1
异步:producer.type=async
request.required.acks=1
queue.buffering.max.ms=5000
queue.buffering.max.messages=10000
queue.enqueue.timeout.ms = -1
batch.num.messages=200
重复消费:
设置offset为自动定时提交,当offset被自动定时提交时,数据还在内存中未处理,此时刚好把线程kill掉,那么offset已经提交,但是数据未处理,导致这部分内存中的数据丢失
26、kafka中的数据已经消费过的数据,是否可以再次消费?怎么做?
auto.commit.enable:如果为true,则consumer的消费偏移offset会被记录到zookeeper。下次consumer启动时会从此位置继续消费。
auto.offset.reset 该参数只接受两个常量largest和Smallest,分别表示将当前offset指到日志文件的最开始位置和最近的位置。