共计 16112 个字符,预计需要花费 41 分钟才能阅读完成。
download:Web3.0 入门与实战 一站式把握 4 大支流区块链开发
摘要
次要的是的针对于的 kafka 的面试的问题进行分析和总结
Partition Rebalance 分区再均衡
1)消费者组中新增加消费者读取到原本是其余消费者读取的消息,(2)消费者敞开或崩溃之后离开群组,原本由他读取的 partition 将由群组里其余消费者读取,(3)当向一个 Topic 增加新的 partition,会发生 partition 在消费者中的重新分配
以上三种景象会使 partition 的所有权在消费者之间转移,这样的行为叫作再均衡。
再均衡的长处:给消费者组带来了高可用性和伸缩性
再均衡的缺点:(1)再均衡期间消费者无奈读取消息,整个群组有一小段时间不可用。(2)partition 被重新分配给一个消费者时,消费者以后的读取状态会丢失,有可能还需要去刷新缓存,在它从新复原状态之前会拖慢应用程序。因此需要进行安全的再均衡和避免不必要的再均衡。
那么消费者组是怎么知道一个消费者可不可用呢?
消费者通过向被指派为群组调和器的 Broker 发送信息来维持它们和群组的从属关系以及它们对分区的所有权关系。只需消费者以失常的工夫间隔发送心跳,就被认为是活跃的,说明它还在读取分区里的消息。消费者会在轮询消息或提交偏移量时发送心跳。如果消费者停止发送心跳的工夫足够长,会话就会过期,群组调和器认为它已经死亡,就会触发一次再均衡。还有一点需要注意的是,当发生再均衡时,需要做一些清理工作,具体的操作方法可能通过在调用 subscribe()方法时传入一个 ConsumerRebalanceListener 实例即可。如何创建消费者创建 Kafka 的消费者对象的过程与创建消费者的过程是类似的,需要传入必要的属性。在创建消费者的时候以下以下三个选项是必选的:
bootstrap.servers:指定 broker 的地址清单,清单里不需要蕴含所有的 broker 地址,消费者会从给定的 broker 里查找 broker 的信息。不过倡导至多要提供两个 broker 的信息作为容错;
key.deserializer:指定键的反序列化器;
value.deserializer:指定值的反序列化器。
Kafka 与传统消息零碎之间有三个要害区别?
(1).Kafka 持久化日志,这些日志可能被重复读取和无限期保留
(2).Kafka 是一个分布式零碎:它以集群的形式运行,可能灵活伸缩,在外部通过复制数据,晋升容错能力和高可用性
(3).Kafka 反对实时的流式处理
Kafka 的用途有哪些?使用场景如何?
总结下来就几个字: 异步处理、日常零碎解耦、削峰、提速、广播。如果再说具体一点例如: 消息, 网站流动追踪, 监测指标, 日志聚合, 流处理, 事件采集, 提交日志等
Kafka 中的 ISR、AR 又代表什么?ISR 的伸缩又指什么?
ISR:In-Sync Replicas 正本同步队列
AR:Assigned Replicas 所有正本
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 中。AR=ISR+OSR。
Kafka 中的 HW、LEO、LSO、LW 等别离代表什么?
HW:High Watermark 高水位,取一个 partition 对应的 ISR 中最小的 LEO 作为 HW,consumer 最多只能生产到 HW 所在的地位上一条信息。
LEO:LogEndOffset 以后日志文件中下一条待写信息的 offset
HW/LEO 这两个都是指最初一条的下一条的地位而不是指最初一条的地位。
LSO:Last Stable Offset 对未实现的事务而言,LSO 的值等于事务中第一条消息的地位(firstUnstableOffset),对已实现的事务而言,它的值同 HW 雷同
LW:Low Watermark 低水位, 代表 AR 会合中最小的 logStartOffset 值
Kafka 中是怎么体现消息次序性的?
kafka 每个 partition 中的消息在写入时都是有序的,生产时,每个 partition 只能被每一个 group 中的一个消费者生产,保障了生产时也是有序的。整个 topic 不保障有序。如果为了保障 topic 整个有序,那么将 partition 调整为 1.
Kafka 中的分区器、序列化器、拦截器是否了解?它们之间的处理次序是什么?
拦截器 -> 序列化器 -> 分区器
Kafka 消费者客户端中使用了几个线程来处理?别离是什么?
2 个,主线程和 Sender 线程。主线程负责创建消息,而后通过分区器、序列化器、拦截器作用之后缓存到累加器 RecordAccumulator 中。Sender 线程负责将 RecordAccumulator 中消息发送到 kafka 中.
“生产组中的消费者个数如果超过 topic 的分区,那么就会有消费者生产不到数据”这句话是否正确?如果不正确,那么有没有什么 hack 的手段??
不正确,通过自定义分分别配策略,可能将一个 consumer 指定生产所有 partition。
消费者提交生产位移时提交的是:以后生产到的最新消息的 offset 还是 offset+1?
offset+1
有哪些情景会造成重复生产?
消费者生产后没有 commit offset(程序崩溃 / 强行 kill/ 生产耗时 / 主动提交偏移情况下 unscrible)
哪些情景下会造成消息漏生产?
消费者没有处理完消息 提交 offset(主动提交偏移 未处理情况下程序异样结束)
KafkaConsumer 是非线程安全的,那么怎么样实现多线程生产?
1. 在每个线程中新建一个 KafkaConsumer
2. 单线程创建 KafkaConsumer,多个处理线程处理消息(难点在于是否要考虑消息次序性,offset 的提交形式)
简述消费者与生产组之间的关系
消费者从属与生产组,生产偏移以生产组为单位。每个生产组可能独立生产主题的所有数据,同一生产组内消费者独特生产主题数据,每个分区只能被同一生产组内一个消费者生产。
当你使用 kafka-topics.sh 创建(删除)了一个 topic 之后,Kafka 背地会执行什么逻辑?
创建: 在 zk 上 /brokers/topics/ 下节点 kafkabroker 会监听节点变动创建主题
删除: 调用脚本删除 topic 会在 zk 上将 topic 设置待删除标记,kafka 后盾有定时的线程会扫描所有需要删除的 topic 进行删除
为什么 Kafka 中的分区数只能减少不能缩小?
当一个主题被创建之后,依然容许咱们对其做肯定的修改,比如修改分区个数、修改配置等,这个修改的功能就是由 kafka-topics.sh 脚本中的 alter 指令所提供。咱们首先来看如何减少主题的分区数。以后面的主题 topic-config 为例,以后分区数为 1,修改为 3,示例如下:
[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh –zookeeper localhost:2181/kafka –alter –topic topic-config –partitions 3
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Adding partitions succeeded!
[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh –zookeeper localhost:2181/kafka –describe –topic topic-config
Topic:topic-config PartitionCount:3 ReplicationFactor:1 Configs:
Topic: topic-config Partition: 0 Leader: 2 Replicas: 2 Isr: 2
Topic: topic-config Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: topic-config Partition: 2 Leader: 1 Replicas: 1 Isr: 1
注意下面提醒的告警信息:当主题中的消息蕴含有 key 时(即 key 不为 null),根据 key 来计算分区的行为就会有所影响。当 topic-config 的分区数为 1 时,不管消息的 key 为何值,消息都会发往这一个分区中;当分区数减少到 3 时,那么就会根据消息的 key 来计算分区号,原本发往分区 0 的消息现在有可能会发往分区 1 或者分区 2 中。如此还会影响既定消息的次序,所以在减少分区数时肯定要三思而后行。对于基于 key 计算的主题而言,倡导在一开始就设置好分区数量,避免当前对其进行调整。目前 Kafka 只反对减少分区数而不反对缩小分区数。比如咱们再将主题 topic-config 的分区数修改为 1,就会报出 InvalidPartitionException 的异样,示例如下:
[root@node1 kafka_2.11-2.0.0]# bin/kafka-topics.sh –zookeeper localhost:2181/kafka –alter –topic topic-config –partitions 1
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Error while executing topic command : The number of partitions for a topic can only be increased. Topic topic-config currently has 3 partitions, 1 would not be an increase.
[2018-09-10 19:28:40,031] ERROR org.apache.kafka.common.errors.InvalidPartitionsException: The number of partitions for a topic can only be increased. Topic topic-config currently has 3 partitions, 1 would not be an increase.
(kafka.admin.TopicCommand$)
为什么不反对缩小分区?
按照 Kafka 现有的代码逻辑而言,此功能残缺可能实现,不过也会使得代码的复杂度急剧增大。实现此功能需要考虑的因素很多,比如删除掉的分区中的消息该作何处置?如果随着分区一起消失则消息的可靠性得不到保障;如果需要保留则又需要考虑如何保留。间接存储到现有分区的尾部,消息的工夫戳就不会递增,如此对于 Spark、Flink 这类需要消息工夫戳(事件工夫)的组件将会受到影响;如果扩散插入到现有的分区中,那么在消息量很大的时候,外部的数据复制会占用很大的资源,而且在复制期间,此主题的可用性又如何失去保障?与此同时,次序性问题、事务性问题、以及分区和正本的状态机切换问题都是不得不面对的。反观这个功能的收益点却是很低,如果真的需要实现此类的功能,残缺可能从新创建一个分区数较小的主题,而后将现有主题中的消息按照既定的逻辑复制过来即可。
创建 topic 时如何抉择合适的分区数?
根据集群的机器数量和需要的吞吐量来决定适合的分区数
Kafka 目前有哪些外部 topic,它们都有什么特色?各自的作用又是什么?
__consumer_offsets 以下划线结尾,保存生产组的偏移
优先正本是什么?它有什么非凡的作用?
优先正本选举次要是为了让所有的分区尽可能分布在不同的 broker 上的一种机制,那么什么是优先正本?优先正本是 AR 种的第一个正本,这个正本通常为 leader,假如这个正本不是 leader,那么这个正本就是非优先正本。
假如咱们通过以下形式创建一个 topic_a, 分区数为 3,正本因子也为 3.
/kafka-topics.sh –create –zookeeper localhost:2181 –partitions 3 –replication-factor 1 –topic topic_a
1.
最终创建的的后果如下
此时 0 号 broker 上的 leader 数量为 2 个,这个节点负载此时最高,1 号节点的负载最低,之前的负载平衡变成了现在的负载失衡,现实状态下优先正本应该就是该分区的 leader 正本,而优先正本的选举就是尽可能的将每个分区的 leader 正本作为优先正本,从而促成集群的负载平衡,然而真正的负载平衡还得参考每个 leader 的数据传输负载
在 kafka 中默认有一个参数管制主动优先正本的选举 auto.leader.rebalance.enable=true, 这个选举机制的间隔工夫通过 leader.imbalance.check.interval.seconds 参数进行管制,默认是 5 分钟 (300s) 一次,这个选举机制的衡量标准是通过“broker 不平衡率”,broker 不平衡率 = 非优先正本的 leader 个数 / 总分区数,假如该值超过 leader.imbalance.per.broker.percentage, 默认为 10%,那么就开始进行优先正本的选举。下面案例的不平衡率 =1/3=33%。记住,在实践上产中是不会开启优先正本选举的,因为可能引起负面的性能问题,比如客户端请求阻塞,所以一般还是通过监控 + 手动管制优先正本的形式来管制集群负载,手动管制通过 bin/kafka-preferred-replica-election.sh –zookeeper localhost:2181/kafka –path-to-json-file election.json 命令进行。
election.json 文件内容示例如下。选举操作应该避开业务高峰期进行,这个 –path-to-json-file 选项是可选的,然而强烈倡导加上这个配置。
{
“partitions”:[
{
"partition":0,
"topic":"topic-partitions"
},
{
"partition":1,
"topic":"topic-partitions"
},
{
"partition":2,
"topic":"topic-partitions"}
]
}
分区重调配?
分区重新分配,次要是在需要进行横向扩大 Broker 的时候或者有计划下线 Broker 的时候使用,假如在 Kafka 集群中新加入了一个 Broker,那么只有新增的 topic 对应的分区才会调配到该节点上,之前的 topic 数据是不会调配给该节点的,这就导致了新增节点与原先节点数据的重大不均衡,所以 kafka 提供了 kafka-reassign-partitions.sh 脚本,在节点扩大、Broker 下线的时候通过数据复制的形式重新分配分区,该脚本的使用分 3 个步骤:
创建一个蕴含主题清单的 json 文件
根据主题清单与 broker 清单生成一份重新分配打算
根据打算执行重调配动作
假设现在有 3 个节点,0,1,2,咱们想要下线 Broker1,而后再重新分配。
第一步,创建一个主题清单的 json 文件:reassign.json
{
“topics”:[
{"topic": "topic-a"}
],
“version”: 1
}
.
第二步,根据主题清单创建一个重新分配的打算, 这个打算可能自己通过 json 的 schema 创建,这样第一步、第二步操作就省去了。
bin/kafka-reassign-partitions.sh –zookeeper localhost:2181/kafka –generate –topics-to-move-json-file reassign.json –broker-list 0,2
1.
生成的清单格局为, 可能将 Current partition replica assignment 保存下来用来做操作的回滚。
Current partition replica assignment
{“version”:1,”partitions”:[]}
Proposed partition reassignment configuration
{“version”:1,”partitions”:[]}
第三步,执行重新分配打算
bin/kafka-reassign-partitions.sh –zookeeper localhost:2181/kafka –execute –reassign-json-file project.json
校验改从新打算的执行情况
bin/kafka-reassign-partitions.sh –zookeeper localhost:2181/kafka –varify –reassign-json-file project.json
如果需要将某个 Broker 下线,那么在执行重新分配打算的时候,最好先敞开或者重启 Broker,这样 Broker 就不再是任何分区的 leader 节点了,这样它的分区就可能被调配给集群中的其它 Broker,这样可能缩小集群间的流量复制,晋升重新分配的性能,以缩小对整个集群的影响。
数据复制限流(配合分区重新分配使用)
主题分区的重新分配是通过数据复制来实现的,首先创建新正本、同步数据、删除旧正本;
数据复制会占用额定的资源,如果复制的量太大,势必会影响整体的性能,特地是在业务高峰期的时候,减小重调配的粒度、以小批次的形式可行,如果集群中某个主题或某个分区 的流量在某段时间内特地大,那么只靠减小粒度是不足以应答的,这时就需要有个限流的机制,可能对正本之间的复制流量加以限度,保障整体不受太大的影响。
正本间的复制限流有 2 种形式:
kafka-config.sh
该脚本次要用来实现动静限流的目标,相干的参数有 2 个
follower.replication.throttled.rate(限度 follower 正本复制的速度)
leader.replication.throttled.rate(限度正本传输的速度,B/s)
增加配置
bin/kafka-configs.sh
–zookeeper localhost:2181/kafka
–entity-type brokers
–entity-name 1
–alter
–add-config
follower.replication.throttled.rate=l024 , leader.replication.throttled.rate=l024
查看配置
bin/kafka-configs.sh
–zookeeper localhost:2181/kafka
–entity-type brokers
–entity-name 1
–describe
删除配置
bin/kafka-configs.sh
–zookeeper localhost:2181/kafka
–entity-type brokers
–entity-name 1
–alter
–delete-config
follower.replication.throttled.rate=l024 , leader.replication.throttled.rate=l024
在 topic 级别也有 2 个参数来限度复制的速度
follower.replication.throttled.replicas
leader.replication.throttled.replicas
1、首先创建一个主题 topic-throttled,partitions=3,replication-factor=2
bin/kafka-topics.sh –create –zookeeper localhost:2181 –partitions 3 –replication-factor 2 –topic topic-throttled
2、查看创建的 topic 的详情
bin/kafka-topics.sh –describe –zookeeper localhost:2181 –topic topic-throttled
3、增加限度复制流量的配置
bin/kafka-config.sh
–zookeeper localhost:2181/kafka
–entity-type topics
–entity-name topic-throttled
–alter
–add-config
leader.replication.throttled.replicas=[0:0,1:1,2:2],follower.replication.throttled.replicas=[0:1,1:2,2:0] #其中 0:0 等代表分区号与代理的映射关系
kafka-reassign-partitions.sh
该脚本也提供了限流的功能,只需要传入一个 throttled 参数就行,具体用法如下:
bin/kafka-reassign-partitions.sh –zookeeper localhost:2181/kafka –execute –reassign-json-file project.json –throttled 10 # 这里的 10 示意 10B/S
1.
Kafka 有哪几处地方有分分别配的概念?简述大抵的过程及原理
创建主题时
如果不手动指定调配形式 有两种调配形式
生产组内调配
简述 Kafka 的日志目录结构
每个 partition 一个文件夹,蕴含四类文件.index/ .log /.timeindex /leader-epoch-checkpoint。.index .log .timeindex 三个文件成对出现 前缀为上一个 segment 的最初一个消息的偏移
log 文件中保存了所有的消息
index 文件中保存了浓密的绝对偏移的索引
timeindex 保存的则是工夫索引,
leader-epoch-checkpoint 中保存了每一任 leader 开始写入消息时的 offset 会定时更新。follower 被选为 leader 时会根据这个必定哪些消息可用。
如果我指定了一个 offset,Kafka 怎么查找到对应的消息?
1. 通过文件名前缀数字 x 找到该相对 offset 对应消息所在文件
2.offset- x 为在文件中的绝对偏移
3. 通过 index 文件中记录的索引找到最近的消息的地位
4. 从最近地位开始逐条寻找
如果我指定了一个 timestamp,Kafka 怎么查找到对应的消息?
1. 通过文件名前缀数字 x 找到该相对 offset 对应消息所在文件
2.offset- x 为在文件中的绝对偏移
3. 通过 index 文件中记录的索引找到最近的消息的地位
4. 从最近地位开始逐条寻找
然而工夫的因为消息体中不带有工夫戳 所以不精确
聊一聊你对 Kafka 的 Log Retention 的理解
kafka 留存策略包含 删除和压缩两种
删除: 根据工夫和大小两个形式进行删除 大小是整个 partition 日志文件的大小,超过的会从老到新顺次删除 工夫指日志文件中的最大工夫戳而非文件的最初修改工夫。
压缩: 雷同 key 的 value 只保存一个 压缩过的是 clean 未压缩的 dirty 压缩之后的偏移量不间断 未压缩时间断
Kafka 有哪些指标需要着重关注?
消费者关注 MessagesInPerSec、BytesOutPerSec、BytesInPerSec 消费者关注生产提早 Lag
怎么计算 Lag?(注意 read_uncommitted 和 read_committed 状态下的不同)
参考 如何监控 kafka 生产 Lag 情况
Kafka 的那些设计让它有如此高的性能?
零拷贝,页缓存,次序写(高效性),分区(扩展性)
Kafka 中的幂等是怎么实现的?
Producer 在生产发送消息时,难免会重复发送消息。Producer 进行 retry 时会产生重试机制,发生消息重复发送。而引入幂等性后,重复发送只会生成一条无效的消息。Kafka 作为分布式消息零碎,它的使用场景常见与分布式零碎中,比如消息推送零碎、业务平台零碎(如物流平台、银行结算平台等)。以银行结算平台来说,业务方作为上游把数据上报到银行结算平台,如果一份数据被计算、处理多次,那么产生的影响会很重大。
影响 Kafka 幂等性的因素有哪些?
在使用 Kafka 时,需要确保 Exactly-Once 语义。分布式零碎中,一些不可控因素有很多,比如网络、OOM、FullGC 等。在 Kafka Broker 确认 Ack 时,出现网络异样、FullGC、OOM 等问题时导致 Ack 超时,Producer 会进行重复发送。可能出现的情况如下:
Kafka 的幂等性是如何实现的?
Kafka 为了实现幂等性,它在底层设计架构中引入了 ProducerID 和 SequenceNumber。那这两个概念的用途是什么呢?
ProducerID:在每个新的 Producer 初始化时,会被调配一个唯一的 ProducerID,这个 ProducerID 对客户端使用者是不可见的。
SequenceNumber:对于每个 ProducerID,Producer 发送数据的每个 Topic 和 Partition 都对应一个从 0 开始枯燥递增的 SequenceNumber 值。
当 Producer 发送消息 (x2,y2) 给 Broker 时,Broker 接收到消息并将其追加到消息流中。此时,Broker 返回 Ack 信号给 Producer 时,发生异样导致 Producer 接收 Ack 信号失败。对于 Producer 来说,会触发重试机制,将消息 (x2,y2) 再次发送,然而,因为引入了幂等性,在每条消息中附带了 PID(ProducerID)和 SequenceNumber。雷同的 PID 和 SequenceNumber 发送给 Broker,而之前 Broker 缓存过之前发送的雷同的消息,那么在消息流中的消息就只有一条(x2,y2),不会出现重复发送的情况。
Kafka 中的事务是怎么实现的?
与幂等性无关的另外一个个性就是事务。Kafka 中的事务与数据库的事务类似,Kafka 中的事务属性是指一系列的 Producer 生产消息和生产消息提交 Offsets 的操作在一个事务中,即原子性操作。对应的后果是同时胜利或者同时失败。这里需要与数据库中事务进行区别,操作数据库中的事务指一系列的增删查改,对 Kafka 来说,操作事务是指一系列的生产和生产等原子性操作。
Kafka 引入事务的用途?
在事务属性引入之前,先引入 Producer 的幂等性,它的作用为:
Producer 多次发送消息可能封装成一个原子性操作,即同时胜利,或者同时失败;
消费者 & 消费者模式下,因为 Consumer 在 Commit Offsets 出现问题时,导致重复生产消息时,Producer 重复生产消息。需要将这个模式下 Consumer 的 Commit Offsets 操作和 Producer 一系列生产消息的操作封装成一个原子性操作。
产生的场景有:
比如,在 Consumer 中 Commit Offsets 时,当 Consumer 在生产实现时 Commit 的 Offsets 为 100(假设最近一次 Commit 的 Offsets 为 50),那么执行触发 Balance 时,其余 Consumer 就会重复生产消息(生产的 Offsets 介于 50~100 之间的消息)。
Kafka 事务提供了哪些可使用的 API?
Producer 提供了五种事务方法,它们别离是:initTransactions()、beginTransaction()、sendOffsetsToTransaction()、commitTransaction()、abortTransaction(),代码定义在 org.apache.kafka.clients.producer.Producer<K,V> 接口中,具体定义接口如下:
// 初始化事务,需要注意确保 transation.id 属性被调配
void initTransactions();
// 开启事务
void beginTransaction() throws ProducerFencedException;
// 为 Consumer 提供的在事务内 Commit Offsets 的操作
void sendOffsetsToTransaction(Map<TopicPartition, OffsetAndMetadata> offsets,
String consumerGroupId) throws ProducerFencedException;
// 提交事务
void commitTransaction() throws ProducerFencedException;
// 放弃事务,类似于回滚事务的操作
vod abortTransaction() throws ProducerFencedException;
事务的实际利用场景有哪些?
在 Kafka 事务中,一个原子性操作,根据操作类型可能分为 3 种情况。情况如下:
只有 Producer 生产消息,这种场景需要事务的染指;
生产消息和生产消息并存,比如 Consumer&Producer 模式,这种场景是一般 Kafka 我的项目中比较常见的模式,需要事务染指;
只有 Consumer 生产消息,这种操作在实际我的项目中意义不大,和手动 Commit Offsets 的后果一样,而且这种场景不是事务的引入目标。
聊一聊你对 Kafka 的 Log Compaction 的理解?
为什么 Kafka 不反对读写分离?
在 Kafka 中,消费者写入消息、消费者读取消息的操作都是与 leader 正本进行交互的,从而实现的是一种主写主读的生产生产模型。数据库、Redis 等都具备主写主读的功能,与此同时还反对主写从读的功能。主写从读也就是读写分离,为了与主写主读对应,这里就以主写从读来称呼。从代码层面上来说,诚然减少了代码复杂度,但在 Kafka 中这种功能残缺可能反对。
1、数据一致性问题
数据从主节点转到从节点,必然会有一个延时的工夫窗口,这个工夫窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X,之后将主节点中 A 的值修改为 Y。那么在这个变更告诉到从节点之前,利用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。
2、延时问题
类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程,需要经历网络→主节点内存→网络→从节点内存这几个阶段,整个过程会耗费肯定的工夫。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历网络→主节点内存→主节点磁盘→网络→从节点内存→从节点磁盘这几个阶段。对延时敏感的利用而言,主写从读的功能并不太实用。主写从读可能均摊肯定的负载,却不能做到残缺的负载平衡。比如对于数据写压力很大而读压力很小的情况,从节点只能摊派很少的负载压力,而绝大多数压力还是在主节点上。而在 Kafka 中却可能达到很大程度上的负载平衡,而且这种均衡是在主写主读的架构上实现的。
有以下几种情况(蕴含但不只限于),会造成肯定程度上的负载不均衡:
broker 端的分分别配不均。当创建主题的时候可能会出现某些 broker 调配到的分区数 多而其余 broker 调配到的分区数少,那么自然而然地调配到的 leader 正本也就不均。
消费者写入消息不均。消费者可能只对某些 broker 中的 leader 正本进行大量的写入操 作,而对其余 broker 中的 leader 正本不闻不问。
消费者生产消息不均。消费者可能只对某些 broker 中的 leader 正本进行大量的拉取操 作,而对其余 broker 中的 leader 正本不闻不问。
leader 正本的切换不均。在实际利用中可能会因为 broker 宕机而造成主从正本的切换,或者分区正本的重调配等,这些动作都有可能造成各个 broker 中 leader 正本的调配不均。
针对第一种情况,在主题创建的时候尽可能使分分别配得均衡,好在 Kafka 中相应的调配算法也是在极力地谋求这一目标,如果是开发人员自定义的调配,则需要注意这方面的内容。
对于第二和第三种情况,主写从读也无奈解决。
对于第四种情况,Kafka 提供了优先正本的选举来达到 leader 正本的均衡。与此同时,也可能配合相应的监控、告警和运维平台来实现均衡的优化。
在实际利用中,配合监控、告警、运维相拆散的生态平台,在绝大多数情况下 Kafka 都能做到很大程度上的负载平衡。
kafka follower 如何与 leader 数据同步?
kafka 使用 ISR 的形式很好的均衡了确保数据不丢失以及吞吐率。Follower 可能批量的从 Leader 复制数据,而且 Leader 充分利用磁盘次序读以及 send file(zero copy)机制,这样极大的提高复制性能,外部批量写磁盘,大幅缩小了 Follower 与 Leader 的消息量差。(kafka 的复制机制既不是残缺的同步复制,也不是单纯的异步复制。残缺同步复制申请 All Alive Follower 都复制完,这条消息才会被认为 commit,这种复制形式极大的影响了吞吐率。一步复制形式下,Follower 异步的从 Leader 复制数据,数据只需被 Leader 写入 log 就被认为已经 commit,这种情况下,如果 leader 挂掉,会丢失数据;)
聊一聊你对 Kafka 底层存储的理解(页缓存、内核层、块层、设施层)?
聊一聊 Kafka 的延时操作的原理?
聊一聊 Kafka 控制器的作用?
生产再均衡的原理是什么?(提醒:消费者调和器和生产组调和器)
Kafka 中有哪些地方需要选举?这些地方的选举策略又有哪些?
生效正本是指什么?有哪些应答措施?
多正本下,各个正本中的 HW 和 LEO 的演化过程
Kafka 在可靠性方面做了哪些改进?(HW, LeaderEpoch)
Kafka 中怎么实现死信队列和重试队列?
Kafka 中的提早队列怎么实现(这题被问的比事务那题还要多!!!据说你会 Kafka,那你说说提早队列怎么实现?)
Kafka 中怎么做消息审计?
Kafka 中怎么做消息轨迹?
Kafka 中有哪些配置参数比较有意义?聊一聊你的见地
Kafka 中有哪些命名比较有意义?聊一聊你的见地
kafka 可能脱离 zookeeper 独自使用吗?为什么?
kafka 不能脱离 zookeeper 独自使用,因为 kafka 使用 zookeeper 治理谐和和 kafka 的节点服务器。
kafka 有几种数据保留的策略?
kafka 有两种数据保存策略:按照过期工夫保留和按照存储的消息大小保留
什么情况会导致 kafka 运行变慢?
cpu 性能瓶颈
磁盘读写瓶颈
网络瓶颈
使用 kafka 集群需要注意什么?
集群的数量不是越多越好,最好不要超过 7 个,因为节点越多,消息复制需要的工夫就越长,整个群组的吞吐量就越低。
集群数量最好是复数,因为超过一半故障集群就不能用了,设置为复数容错率更高。
Kafka 判断一个节点是否还活着有那两个条件?
(1)节点必须可能保护和 ZooKeeper 的连接,Zookeeper 通过心跳机制查看每个节点的连接
(2)如果节点是个 follower, 他必须能及时的同步 leader 的写操作,延时不能太久
Kafka 消费者是否可能生产指定分区消息?
Kafa consumer 生产消息时,向 broker 收回 fetch 请求去生产特定分区的消息,consumer 指定消息在日志中的偏移量(offset),就可能生产从这个地位开始的消息,customer 具备了 offset 的控制权,可能向后回滚去从新生产之前的消息,这是很有意义的。
消费者负载平衡策略?
一个消费者组中的一个分片对应一个消费者成员,他能保障每个消费者成员都能拜访,如果组中成员太多会有空闲的成员。
Kafka 的消费者如何生产数据?
1、指定多主题生产:consumer.subscribe(Arrays.asList(“t4”,“t5”));
2、指定分区生产:consumer.assign(list);
3、手动修改偏移量:consumer.commitSync();// 提交以后生产偏移量 consumer.commitSync(Map<TopicPartition, OffsetAndMetadata>) // 提交指定偏移量 consumer.assign(Arrays.asList(tp));
4、seek,修改偏移量搜寻指针,次序读取数据:consumer.assign(Arrays.asList(tp));consumer.seek(tp,0);
partition 的数据如何保存到硬盘
topic 中的多个 partition 以文件夹的形式保存到 broker,每个分区序号从 0 递增,且消息有序
Partition 文件下有多个 segment(xxx.index,xxx.log)
segment 文件里的 大小和配置文件大小一致可能根据申请修改 默认为 1g。如果大小大于 1g 时,会滚动一个新的 segment 并且以上一个 segment 最初一条消息的偏移量命名
kafka 如何保证数据数据有序?
一个消费者组里它的外部是有序的,消费者组与消费者组之间是无序的。
kafka 数据一致性保障?
假设分区的正本为 3,其中正本 0 是 Leader,正本 1 和正本 2 是 follower,并且在 ISR 列表外面。诚然正本 0 已经写入了 Message4,然而 Consumer 只能读取到 Message2。因为所有的 ISR 都同步了 Message2,只有 High Water Mark 以上的消息才反对 Consumer 读取,而 High Water Mark 取决于 ISR 列表外面偏移量最小的分区,对应于上图的正本 2,这个很类似于木桶原理。
这样做的原因是还没有被足够多正本复制的消息被认为是“不安全”的,如果 Leader 发生崩溃,另一个正本成为新 Leader,那么这些消息很可能丢失了。如果咱们容许消费者读取这些消息,可能就会破坏一致性。试想,一个消费者从以后 Leader(正本 0)读取并处理了 Message4,这个时候 Leader 挂掉了,选举了正本 1 为新的 Leader,这时分另一个消费者再去从新的 Leader 读取消息,发现这个消息其实并不存在,这就导致了数据不一致性问题。
当然,引入了 High Water Mark 机制,会导致 Broker 间的消息复制因为某些原因变慢,那么消息到达消费者的工夫也会随之变长(因为咱们会先等待消息复制完毕)。延迟时间可能通过参数 replica.lag.time.max.ms 参数配置,它指定了正本在复制消息时可被容许的最大延迟时间。
Kafka 存储在硬盘上的消息格局是什么?
消息由一个固定长度的头部和可变长度的字节数组组成。头部蕴含了一个版本号和 CRC32 校验码。
消息长度: 4 bytes (value: 1+4+n)
版本号: 1 byte
CRC 校验码: 4 bytes
具体的消息: n bytes
Kafka 高效文件存储设计个性:
(1).Kafka 把 topic 中一个 parition 大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经生产完文件,缩小磁盘占用。
(2). 通过索引信息可能疾速定位 message 和必定 response 的最大大小。
(3). 通过 index 元数据全副映射到 memory,可能避免 segment file 的 IO 磁盘操作。
(4). 通过索引文件浓密存储,可能大幅升高 index 文件元数据占用空间大小。