1、Kafka中的AR、ISR、OSR又代表什么?
AR(AllReplicas):分区的所有副本(AR=ISR+OSR)
ISR(InSyncReplicas):与leader保持同步的follower集合
OSR(OutSyncReplicas):ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms
和延迟条数replica.lag.max.messages
两个维度, 当前最新的版本0.10.x中只支持replica.lag.time.max.ms
这个维度),任意一个超过阈值都会把follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中
OSR中的副本,如果与leader通信后,会尝试与leader同步,同步的策略是首先将当前记录的hw之后的消息删除,然后与leader同步,当与leader基本同步之后(存储的消息的offset大于当前isr中的hw),就重新回到isr之中
2、Kafka中的LEO、HW等分别代表什么?
LEO(Log End Offset):指的是每个副本最大的offset
HW(High Watermark):指的是消费者能见到的最大的offset,ISR队列中最小的LEO
3、Kafka中是怎么体现消息顺序性的?
每个分区内,每条消息都有一个offset,故智能保证分区内有序
kafka每个partition中的消息在写入时都是有序的,消费时每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的
整个topic不保证有序,如果为了保证topic整个有序,那么将partition调整为1
4、Kafka中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?
分区器:根据键值确定消息应该处于哪个分区中,默认情况下使用轮询分区,可以自行实现分区器接口自定义分区逻辑
序列化器:键序列化器和值序列化器,将键和值都转为二进制流还有反序列化器将二进制流转为指定类型数据
拦截器:两个方法doSend()方法会在序列化之前完成,onAcknowledgement()方法在消息确认或失败时调用可以添加多个拦截器按顺序执行
处理顺序:拦截器 --> 序列化器 --> 分区器
5、Kafka生产者客户端的整体结构是什么样子的?使用了几个线程来处理?分别是什么?
2个线程,主线程和Sender线程
主线程:负责创建消息,然后通过分区器、序列化器、拦截器作用之后缓存到累加器(RecordAccumulator)中
Sender线程:负责将RecordAccumulator中消息发送到kafka中
6、“消费组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据”这句话是否正确?
正确,因为一个分区只能被同一个消费组中的一个消费者消费,如果消费者组中消费者个数超过分区数,那么肯定有一个没有办法消费到数据
7、消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?
offset + 1
8、有哪些情形会造成重复消费?
- 当ack=-1时,如果在follower同步完成后,broker发送ack之前,leader发生故障,导致没有返回ack给producer,由于失败重试机制,又会给新选举出来的leader发送数据,造成数据重复
- 手动管理offset时,先消费后提交offset,消费者消费后没有commit offset(程序崩溃/强行kill/消费耗时/自动提交偏移情况下unscrible)
9、那些情景会造成消息漏消费?
- 手动管理offset时,先提交offset后消费,有可能造成数据的漏消费
- 当ack=0时,producer不等待broker的ack,这一操作提供了一个最低的延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时有可能丢失数据
- 当ack=1时,producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,而由于已经返回了ack,系统默认新选举的leader已经有了数据,从而不会进行失败重试,那么将会丢失数据
10、当你使用kafka-topics.sh创建(删除)了一个topic之后,Kafka背后会执行什么逻辑?
- 会在zookeeper中的
/brokers/topics
节点下创建一个新的topic节点,如:/brokers/topics/first
- 触发Kafka Controller的监听程序
- Kafka Controller负责topic的创建工作,并跟新metadata cache
11、topic的分区数可不可以增加?如果可以怎么增加?如果不可以,那又是为什么?
可以增加
可以通过命令增加:bin/kafka-topics.sh --zookeeper bigdata02:2181/kafka --alter --topic topic-config --partitions 3
也可以通过Kafka Manager等图形化管理工具进行分区的添加
12、topic的分区数可不可以减少?如果可以怎么减少?如果不可以,那又是为什么?
不可以减少,被删除的分区数据难以处理
13、Kafka有内部的topic吗?如果有是什么?有什么所用?
__consumer_offsets
,以双下划线开头,保存消费组的偏移量
14、Kafka分区分配的概念?
一个topic多个分区,一个消费者组中有多个消费者,故需要将分区分配给消费者(Range、RoundRobin)
Range是默认策略。Range是对每个topic而言的(即一个topic一个topic的分),首先对同一个topic里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序;然后用partitions分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区;如果除不尽,那么前面几个消费者线程将会多消费一个分区
RoundRobin分区分配策略的前提是同一个消费者组里面的所有消费者的num.streams(消费者消费线程数)必须相等;每个消费者订阅的主题必须相同。首先将所有主题分区组成TopicAndPartition列表,然后对TopicAndPartition列表按照hashCode进行排序,最后按照轮询的方式发给每一个消费线程
15、简述Kafka的日志目录结构?
每个分区对应一个文件夹,文件夹的命名为topic-0
,topic-1
,内部为.log
和.index
文件
每个partition一个文件,包含四类文件:.index
、.log
、.timeindex
、leader-epoch-checkpoint
.index .log .timeindex三个文件成对出现,前缀为上一个segment的最后一个消息的偏移
log文件中保存了所有的消息
index文件中保存了稀疏的相对偏移的索引
timeindex保存的则是时间索引
leader-epoch-checkpoint中保存了每一任leader开始写入消息时的offset,会定时更新,follower被选为leader时会根据这个确定哪些消息可用
16、如果我指定了一个offset,Kafka Controller怎么查找到对应的消息?
- 先二分查找获取对应index索引文件,获取到对应的物理offset
- 拿着物理offset去log数据文件顺序查找对应消息
- 返回查找找到的消息
17、聊一聊Kafka Controller的作用?
负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作
在kafka集群中会有一个或者多个broker,其中有一个broker会被选举为控制器(kafka controller),它负责管理整个集群中所有分区和副本的状态
当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本
当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息
当使用kafka-topic.sh脚本为某个topic增加分区数量时,同样还是由控制器负责分区的重新分配
18、Kafka中有那些地方需要选举?这些地方的选举策略又有哪些?
partition leader(ISR)
kafka controller(先到先得)
当broker启动时,会尝试去创建/controller节点,创建成功即成为controller;如果该controller死亡,/controller节点会释放,由新的broker创建此节点成为新的controller
19、失效副本是指什么?有那些应对措施(Kafka的ISR副本同步队列)?
不能及时与leader同步,暂时踢出ISR,等其追上leader之后再重新加入
ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms
和延迟条数replica.lag.max.messages
两个维度, 当前最新的版本0.10.x中移除了replica.lag.max.messages
参数,防止服务频繁的进去队列),任意一个超过阈值都会把follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中
OSR中的副本,如果与leader通信后,会尝试与leader同步,同步的策略是首先将当前记录的hw之后的消息删除,然后与leader同步,当与leader基本同步之后(存储的消息的offset大于当前ISR中的HW),就重新回到ISR之中
20、Kafka的哪些设计让它有如此高的性能(Kafka高效读写能力)?
-
kafka本身式分布式集群,同时采用分区技术,并发度高
-
顺序写磁盘
kafka的producer生产数据,要写入到log文件中,写的过程是一直追加到文件末端,为顺序写
官网有数据表明,同样的磁盘,顺序写能到600M/s,而随机写只有100K/s
-
零拷贝技术(0-copy)
21、kafka单条数据大小是多大?
kafka对于消息提的大小默认单条最大值是1M,但是在我们应用场景中,常常会出现一条消息大于1M,如果不对kafka进行配置,则会出现生产者无法将消息推送到kafka或消费者无法去消费kafka里面的数据,这时我们就要对kafka进行以下配置:server.properties
# broker可复制的消息的最大字节数, 默认为1M
replica.fetch.max.bytes: 1048576
# kafka会接收单个消息size的最大限制,默认为1M左右
message.max.bytes: 1000012
注意:message.max.bytes必须小于等于replica.fetch.max.bytes,否则就会导致replica之间数据同步失败
22、kafka如何清理过期数据?
保证数据没有被引用(没人消费它)
日志清理保存的策略只有delete和compact两种
# 启用删除策略
log.cleanup.policy=delete
# 启用压缩策略
log.cleanup.policy=compact
23、Kafka可以按照时间消费数据?
Map<TopicPartition, OffsetAndTimestamp> startOffsetMap = KafkaUtil.fetchOffsetsWithTimestamp(topic, sTime, kafkaProp);
24、消费者消费数据–zookeeper和–bootstrap-server的区别是什么?
对于消费者,kafka中有两个设置的地方:对于老的消费者,由–zookeeper参数设置;对于新的消费者,由–bootstrap-server参数设置
如果使用了–zookeeper参数,那么consumer的offset信息将会存放在zookeeper之中,查看的方法是使用./zookeeper-client
,然后ls /consumer/[group_id]/offset/[topic]/[broker_id-part_id]
,这个是查看某个group_id的某个topic的offset
如果使用了–bootstrap-server参数,那么consumer的信息将会存放在kafka之中
25、Kafka消费者角度考虑是拉取数据还是推送数据?
拉取数据
26、Kafka中的数据是有序的么?
单分区内有序
多分区,分区与分区间无序
27、Kafka的机器数量?
Kafka机器数量 = 2 * (峰值生产速度 * 副本数 / 100) + 1
28、副本数设定?
一般我们设置成2个或3个,很多企业设置为2个
副本的优势:提高可靠性
副本的劣势:增加了网络IO传输
29、Kafka压测?
Kafka官方自带压力测试脚本(kafka-consumer-perf-test.sh、kafka-producer-perf-test.sh)
Kafka压测时,可以查看到哪个地方出现了瓶颈(CPU、内存、网络IO)
一般都是网络IO达到瓶颈
30、Kafka日志保存时间?
默认保存7天,生产环境建议3天
31、Kafka中数据量计算?
每天总数据量100g,每天产生1亿条日志,1亿/24/60/60=1150条/s
平均每秒钟:1150条
低谷每秒钟:50条
高峰每秒钟:1150 * (2-20倍) = 2300-23000条
每条日志大小:0.5-2k(取1k)
每秒多少数据量:2-20M
32、Kafka的硬盘大小?
每天的数据量100g * 2个副本 * 3天 / 70%
33、Kafka监控?
公司自己开发的监控
开源的监控器:KafkaManager、KafkaMonitor、KafkaEagle
34、Kafka分区?
- 创建一个只有1个分区的topic
- 测试这个topic的producer吞吐量和consumer吞吐量
- 假设它们的值分别是Tp和Tc,单位可以是MB/s
- 然后假设总的目标吞吐量是Tt,那么分区数 = Tt/min(Tp,Tc)
假如:producer吞吐量=20m/s,consumer吞吐量=50m/s,期望吞吐量100m/s
分区数 = 100 / 20 = 5分区
分区数一般设置为:3-10个
35、多少个topic?
通常情况:多少个日志类型就多少个topic,也有对日志类型进行合并的
36、Kafka挂掉?
- Flume记录
- 日志有记录
- 短期没事
37、Kafka丢不丢数据?
- ack=0,相当于异步发送,消息发送完毕即offset增加,继续生产
- ack=1,leader收到leader replica对一个消息的接受ack才增加offset,然后继续生产
- ack=-1,leader收到所有replica对一个消息的接受ack才增加offset,然后继续生产
38、Kafka数据重复?
幂等性 + ack-1 + 事务
Kafka数据重复,可以再下一级:SparkStreaming、redis或者hive中dwd层去重
去重的手段:分组、按照id开窗只取第一个值
39、Kafka幂等性?
Kafka0.11版本引入了幂等性,幂等性配合at least once语义可以实现exactly once语义
但只能保证单次会话的幂等
40、Kafka消息数据积压,Kafka消费能力不足怎么处理?
- 如果是kafka消费能力不足,则可以考虑增加topic的分区数,并且同时提升消费组的消费者数量,消费者数=分区数(两者缺一不可)
- 如果是下游的数据处理不及时:提升每批次拉取的数量;批次拉取数据过少(拉取数据 / 处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压
41、Kafka事务
Kafka0.11版本引入Kafka的事务机制,其可以保证生产者发往多个分区的一批数据的原子性
42、Kafka参数优化?
Broker参数配置(server.properties)
-
日志保留策略配置
# 保留三天,也可以更短(log.cleaner.delete.retention.ms) log.retention.hours=72
-
Replica相关配置
# 默认副本1个 default.replication.factor:1
-
网络通信延时
# 当集群之间网络不稳定时,调大该参数 replica.socket.timeout.ms:30000 # 如果网络不好或者kafka集群压力较大,会出现副本丢失,然后会频繁复制副本,导致集群压力更大,此时可以调大该参数 replica.lag.time.max.ms= 600000
Producer优化(producer.properties)
# 默认发送不进行压缩,推荐配置一种适合的压缩算法,可以大幅度的减缓网络压力和Broker的存储压力
compression.type:none
GZIP、Snappy和LZ4,从2.1.0开始,kafka正式支持Zstandard算法(简写zstd),它是Facebook开源的一个压缩算法,能够提供超高的压缩比
对于kafka测试而言
在吞吐方面:LZ4 > Snappy > zstd、GZIP
在压缩比方面:zstd > LZ4 > GZIP > Snappy
具体到物理资源,使用Snappy算法占用的网络带宽资源最多,zstd最少,这是合理的,毕竟zstd就是要提供超高的压缩比
在CPU使用率方面,各个算法表现的差不多,只是在压缩时Snappy使用的CPU较多一些
而在解压缩时GZIP算法则可能使用更多的CPU
Kafka内存调整(kafka-server-start.sh)
# 默认内存1个G,生产环境尽量不要超过6个G
export KAFKA_HEAP_OPTS="-Xms4g -Xmx4g"
供超高的压缩比
对于kafka测试而言
在吞吐方面:LZ4 > Snappy > zstd、GZIP
在压缩比方面:zstd > LZ4 > GZIP > Snappy
具体到物理资源,使用Snappy算法占用的网络带宽资源最多,zstd最少,这是合理的,毕竟zstd就是要提供超高的压缩比
在CPU使用率方面,各个算法表现的差不多,只是在压缩时Snappy使用的CPU较多一些
而在解压缩时GZIP算法则可能使用更多的CPU
Kafka内存调整(kafka-server-start.sh)
# 默认内存1个G,生产环境尽量不要超过6个G
export KAFKA_HEAP_OPTS="-Xms4g -Xmx4g"